Question

This has me stumped. I have an array of urls (for data) which I need to pull into the page and process the results once all are loaded. I am attempting to use JQuerys Deffered functionality to ensure that all of the ajax calls have completed before I process the results. As soon as I introduced it (the when().done() functionality), my responseText magically disappeared.

My simplest example:

$.when([$.ajax("pathToData")]).done(
    function(results) {
        console.log(results[0]);               //object with a responseText attribute
        console.log(results[0].responseText);  //undefined !!!
    }
)

I suspect I am missing something simple, but the more I read the documentation the more this looks correct. I'm hoping someone else can spot the issue easily and point me in the right direction. Thanks in advance!

Was it helpful?

Solution

The weird behaviour you're seeing is a limitation of the console, and actually nothing to do with your code.

The resolution of the properties of the object are deferred until you expand the Object in the console. By that time the AJAX request has completed and responseText is available. However, the value of results[0].responseText is resolved immediately as undefined.

If you did:

$.when([$.ajax({
    url: '/echo/json/',
    type: 'POST',
    data: {json: '{"a":12}'}
})]).done(function(results) {
    console.log(JSON.stringify(results[0])); //object with a responseText attribute
    console.log(results[0].responseText); //undefined !!!
})​

You'll see:

{"readyState": 1}
undefined

Instead.


As to how to solve your problem; I've never known $.when() to accept arrays, nor does the documentation say it does. Because of this, when() seems to be executing the done() immediately, as the array is not a deferred (per the docs):

If a single argument is passed to jQuery.when and it is not a Deferred, it will be treated as a resolved Deferred and any doneCallbacks attached will be executed immediately.

Instead pass your AJAX request(s) as separate parameters, as shown in the docs:

$.when($.ajax('a'), $.ajax('b')).done(function (a, b) {
  // a & b = [ "success", statusText, jqXHR ]
});

As such:

$.when($.ajax({
    url: '/echo/json/',
    type: 'POST',
    data: {json: '{"a":12}'}
}), $.ajax({
    url: '/echo/json/',
    type: 'POST',
    data: {json: '{"b":12}'}
})).done(function(a, b) {
    console.log(a[2].responseText);
    console.log(b[2].responseText);    
})​;

There you get:

{"a": 12}
{"b": 12} 

... and an updated fiddle: http://jsfiddle.net/39mHw/2/

OTHER TIPS

What gets set to results is an array representing 3 things - the textStatus (i.e. "success"), statusText, and jqXHR object - in that order.

You need to access array position 2 to get jqXHR object which has the responseText attribute. So simply change your index values like this:

$.when($.ajax("pathToData")).done(
    function(results) {
        console.log(results[2]);               //object with a responseText attribute
        console.log(results[2].responseText);  //undefined !!!
    }
)

Note that I have removed the array brackets around the ajax() function call here.

Here is an exact example from jQuery when() page ( http://api.jquery.com/jQuery.when ):

$.when($.ajax("/page1.php"), $.ajax("/page2.php")).done(function(a1,  a2){
    /* a1 and a2 are arguments resolved for the 
        page1 and page2 ajax requests, respectively */
   var jqXHR = a1[2]; /* arguments are [ "success", statusText, jqXHR ] */
   if ( /Whip It/.test(jqXHR.responseText) ) {
      alert("First page has 'Whip It' somewhere.");
   }
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top