Faciō

A Selection of Stuff I Make and Think About

Faciō
  • Sustainability
  • Web
  • Design
  • Other Projects
  • About Me

Leave a Comment

Updated on May 19, 2015

Call a previous AJAX request again

by Maurits

For a project I was trying to solve the issue of session timeouts while not frustrating the user after an ajax call. So the previous ajax call had to be saved and executed again after a successful log-in.

For example you have some management system that is open for a long time, but for safety sessions are not kept alive too long. However people might find themselves in the situation that they were still working on something while their session expired. So it would be nice for a user to execute an action, be prompted with a log-in form, and if it succeeds the original ajax call will automatically be made.

I used the CodeIgniter platform which has some nice functions to set the headers as well as jQuery for easy ajax handling. In the solution I propose it would be best to have proper handling of request headers. As W3C specs define the 401 Unauthorized is returned in case:

  • the request requires user authentication.
  • If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials.*

* i.e. the credentials were wrong or the the person is just not authorized

So to achieve this you first want to keep track of previous ajax calls. First of all we will extend the jQuery ajax object with an extra array called mostRecentCalls.

1
2
3
$(document).ready(function(){
	$.ajax.mostRecentCalls = [];
})

$(document).ready(function(){ $.ajax.mostRecentCalls = []; })

Then we keep track of each completed ajax call using $.ajaxComplete();
Because you might have several different ajax call throughout your website that should not interfere (for example timed polling of messages or notifications, some user statistics polling, etc.) it would be best to define namespaces for each type of ajax request that you want to keep the most recent from.

1
2
3
4
5
6
7
8
9
$(document).ajaxComplete( function(ev, jqXHR, settings){
	if(!(settings.namespace === false || typeof settings.namespace === 'undefined')){
		// create new namespace if it does not exist yet.
		if(!$.isArray($.ajax.mostRecentCalls[settings.namespace])){
			$.ajax.mostRecentCalls[settings.namespace] = [];
		}
		$.ajax.mostRecentCalls[settings.namespace] = settings;
	}
});

$(document).ajaxComplete( function(ev, jqXHR, settings){ if(!(settings.namespace === false || typeof settings.namespace === 'undefined')){ // create new namespace if it does not exist yet. if(!$.isArray($.ajax.mostRecentCalls[settings.namespace])){ $.ajax.mostRecentCalls[settings.namespace] = []; } $.ajax.mostRecentCalls[settings.namespace] = settings; } });

In our ajax call we can then access the previous ajax call. Generall your current ajax call probably looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
$.ajax({
	url: 'my/request/url',
	data: myDataObj,
	success: function(data){
		// data will be object with your content,
		// set it as content to your object
		$(target).html(data.myHtml);
	},
	error: function(response){
		alert('an error occured')
	}
})

$.ajax({ url: 'my/request/url', data: myDataObj, success: function(data){ // data will be object with your content, // set it as content to your object $(target).html(data.myHtml); }, error: function(response){ alert('an error occured') } })

Yes, it’s not very neat error handling, but its just an example. You might also have defined deferred object methods like .done() and .fail(), however to make this work neatly you must extend the ajax object with at least the success callback as above. This way we can just have the previous saved settings used for the $.ajax object and all is set.
So how would that look like:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
$.ajax({
	url: '',
	namespace: 'SPECIFIC_AJAX_CALL_ID',
 
	// success callback must be in the $.ajax object
	success: function(data){
		// successful request, do whatever you want :)
		$(target).html(data.myHtml);
	},
 
	// error callback may be in the $.ajax object, but can also be set as deferred .fail() method
	// error function shows the log-in form in case of 401 response
	error: function(response){
		if(response.status == 401){
			// move login form to your target 
			// (assumed you already have a login form somewhere ;))
			$(target).html($('#login-form'));
 
			// handle the log-in form
			$('#form-login', $(target)).on('submit', function(e){
 
				// submit the form by ajax
				$.ajax({
					url: $('#form-login').attr('action'),
					type: $('#form-login').attr('method'),
					data: $( '#form-login' ).serialize()	
				})
				.done(function(response){
					// execute previous ajax call
					$.ajax( $.ajax.mostRecentCalls['SPECIFIC_AJAX_CALL_ID'] );
				})
				.fail(function(response){
					// show the log-in form once more, now with an error
					$('h2', '#form-login').after('Your credentials were wrong.') 
					$('#form-login').get(0).reset(); 
				}) 
				e.preventDefault();
				return false; 
			}) 
		} 
	} 
})

$.ajax({ url: '', namespace: 'SPECIFIC_AJAX_CALL_ID', // success callback must be in the $.ajax object success: function(data){ // successful request, do whatever you want :) $(target).html(data.myHtml); }, // error callback may be in the $.ajax object, but can also be set as deferred .fail() method // error function shows the log-in form in case of 401 response error: function(response){ if(response.status == 401){ // move login form to your target // (assumed you already have a login form somewhere ;)) $(target).html($('#login-form')); // handle the log-in form $('#form-login', $(target)).on('submit', function(e){ // submit the form by ajax $.ajax({ url: $('#form-login').attr('action'), type: $('#form-login').attr('method'), data: $( '#form-login' ).serialize() }) .done(function(response){ // execute previous ajax call $.ajax( $.ajax.mostRecentCalls['SPECIFIC_AJAX_CALL_ID'] ); }) .fail(function(response){ // show the log-in form once more, now with an error $('h2', '#form-login').after('Your credentials were wrong.') $('#form-login').get(0).reset(); }) e.preventDefault(); return false; }) } } })

Good luck!

Category: Faciō, Web Tags: Ajax, log in, previous request

← DoToKnow
CIRP Citation Style for Mendeley →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts
  • 8 Domains of Circularity
  • 10 Enablers of the Circular Economy
  • A hype of economic paradigms!?
  • An extensive history of the Circular Economy
  • Risks of the Circular Economy
Fetch Tweets: Could not authenticate you. Code: 32
Categories
  • Circular Economy
  • Design
  • Faciō
  • Fun with type
  • Projects
  • Sustainability
  • Web
Favourite Links
  • Bewustheel
  • Studentenvereniging AEGEE-Enschede
Archives
  • February 2016
  • January 2016
  • September 2015
  • June 2015
  • May 2015
  • February 2015
  • April 2014
  • March 2014
  • February 2014
  • October 2013
  • July 2013
  • February 2013

Copyright © 2025 · All Rights Reserved · Faciō

Swell Lite from Organic Themes · RSS Feed

  • Twitter
  • LinkedIn