jQuery Promises – Taking action .when() multiple ajax calls are complete

jQuery.when() – “Provides a way to execute callback functions based on one or more objects, usually Deferred objects that represent asynchronous events”

https://api.jquery.com/jQuery.when/

Wouldn’t it be nice to be able to know when two ajax calls are both complete – and then process the data returned from both, at the same time ?

Callbacks

Off the top of my head I would normally achieve this using a callback – and I have done so in some of my ExtJS in XPages articles. The following code snippet creates a callback that once the $.ajax call the url is complete take the data and pass it to the createGrid function. In there I could make another ajax call and then when that is complete I could process both data sets.

function getGridData(url, callback){

	var dataURL = url
	$.ajax({
		  url: dataURL+"&rand="+aRandomNumber()+"&"
		}).done(function ( data ) {
			//one the data is loaded then pass it to the callback function
			//passed in as one of the function arguments
			if(callback){
				callback(data)
			}
		});
}

var url = location.href
url = (url.indexOf('5Col')>-1) ? '5Col' : ""

url = 'xRestService.xsp/byFirstNameFlat'+url+'?count=100000'
var theData
var theCallBack = function(theData){
		createGrid(theData)
		}
getGridData(url, theCallBack)

This kinda makes an synchronous linear usage of asynchronous calls – do this then do that

As inelegant as that it, it works. The problems really start when you have 3, 4 or more callbacks and you get a callback hell of what if something fails in the middle and you have to run back up the tree looking for a fail – not pretty.

Using jQuery.when()

Modern browsers support the Promises concept which natively allows us to do the same thing but we know what that means and not the browsers we code for today.

.when() gives us the ability to pass as many ajax calls as we like, and then create one line of code which processes all the answers together.

Example

Here is a simple REST service feed from an XPages URL (fakenames data)

http://copper.xomino.com/xomino/extjs.nsf/xRestService.xsp/byFirstNameFlat?count=5

[
  {
      "@entryid":"1-AE3FB4C32057B87C85257C22000A83DD",
      "@unid":"AE3FB4C32057B87C85257C22000A83DD",
      "@noteid":"F5CA",
      "@position":"1",
      "@siblings":1304,
      "@form":"fUserName",
      "noteid":"NT0000F5CA",
      "firstname":"Alfred",
      "lastname":"Hall",
      "address":"2139 Jail Drivedd",
      "city":"Tremont",
      "state":"FL",
      "zip":615680,
      .........
  }
]

Which is nice ‘n all, but if we then wanted to know what State FL was (remember this is an example)

At the same time as pulling in the person you could also pull a list of US states

http://copper.xomino.com/xomino/extjs.nsf/states.json

{
    "AL": "Alabama",
    "AK": "Alaska",
    "AS": "American Samoa",
    "AZ": "Arizona",
    "AR": "Arkansas",
    "CA": "California",
    "CO": "Colorado",
    "CT": "Connecticut",
    "DE": "Delaware",
    "DC": "District Of Columbia",
    "FM": "Federated States Of Micronesia",
    "FL": "Florida",
    "GA": "Georgia",
    ......

From that we can then do a cross reference and display something useful.

The $.when returns each element as an Array of data so we have to get the zeroth value of each object returned to access it’s key/pairs

$.when(
    $.ajax({
        url: "xRestService.xsp/byFirstNameFlat?count=5",
        dataType: "json"
    }),
    $.ajax({
        url: "states.json",
        dataType: "json"
    })
).done(function( people, states ) {
    for (var i=0; i < people[0].length; i++){
        var person = people[0][i]
        var temp = ""
        temp=temp+person.firstname+" "
        temp=temp+person.lastname+" lives in "
        temp=temp+states[0][person.state]
        console.log(temp)
    }

});

As you can see from the screenshots below – the ajax calls can be executed in either order and still the result stands because the .done() function is not run until both are complete

d2

d1

d3

 

 

Conclusion

This is a very interesting capability which has apparently been around for ages and I wish I had known about it earlier (added jQuery v1.5)

 

3 thoughts on “jQuery Promises – Taking action .when() multiple ajax calls are complete

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s