JQuery when () then () results in no ajax responseText

It puzzled me. I have an array of URLs (for data) that I need to pull into a page and process the results after they load. I am trying to use JQuerys Deffered functionality to make sure all ajax calls are complete before processing the results. As soon as I entered it (when (). Done () function), my Text answer magically disappeared.

The 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 that I am missing something simple, but the more I read the documentation, the more it looks right. I hope someone else can easily understand the problem and point me in the right direction. Thanks in advance!

+4
source share
2 answers

The strange behavior you see is a limitation of the console and actually has nothing to do with your code.

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

If you have done this:

 $.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 will see:

 {"readyState": 1} undefined 

Instead.


How to solve your problem; I never knew that $.when() accepts arrays, and the documentation doesn't say that. Because of this, when() seems to execute done() immediately, since the array is not deferred (for documents):

If one argument is passed to jQuery.when and it is not deferred, it will be considered as resolved by Deferred, and any attached doneCallbacks files will be executed immediately.

Instead, pass your AJAX requests as separate parameters, as shown in the docs:

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

In this way:

 $.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 will receive:

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

... and updated script: http://jsfiddle.net/39mHw/2/

+4
source

What is set to results is an array representing 3 things β€” textStatus (ie, β€œsuccess”), statusText, and the jqXHR object β€” in that order.

You need to access a level 2 position to get a jqXHR object that has a responseText attribute. Therefore, simply change the index values ​​as follows:

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

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

Here is an exact example from the 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."); } }); 
0
source

All Articles