I am trying to update array values using the response from multiple getJSON requests. I have tried this a number of ways and the snippet below is the simplest form I have used. The individual success callbacks have not updated the array by the time the .then() fires so the alert shows the original values. I have also tried to store the individual jqXHR objects in an array and work through them, but they are all readyState: 1. Any suggestions on how to get a reference to the responses after they have all completed?
$(function() {
var points = [['A', 12946],
['B', 4223],
['C', 2774],
];
function makePointCalls(i) {
return $.getJSON("http://otter.topsy.com/searchcount.json?callback=?",
{
q: points[i][0]
},
function(data) {
points[i][1] = data.response.d;
}
);
}
$.when($.each(points, function(i, value){
makePointCalls(i);
})
).then(function(){
//alert me after all the getJSONs are done and array updated?
alert(points);
});
});//doc ready
Your code needs to react on the return value of
makePointCallswhich is discarded in youreachloop.Untested code fragments follow (working according to kas673’s comment):
Note the use of
mapinstead ofeachto create an array with the return values (deferreds) ofmakePointCalls. The call toapplyfor invokingwhenis there to ensurewhenreceives its parameters in the documented format. If you would pass an array towhenas sole argument it could just assume it received an resolved deferred and execute the function inthenimmediately.A more verbose explanation regarding the use of apply is that
whenassumes everything is a resolved deferred that is not a deferred. First of all one needs to note that a deferred is some sort of callback manager. It holds callbacks to invoke on success/resolve and callbacks for failure/rejection. Deferreds are used to provide a return value for which it is only known at a later time whether the function invocation was successful. An example is your AJAX request that needs to wait for the server but should not block the JavaScript execution.Each of your calls to
$.getJSONreturns a deferred which can be used to react on the requests completion.$.whentakes any number of deferreds as its arguments and invokesthen‘s argument as soon as the aggregate state of the deferreds is known (either when all arguments towhenare resolved or at least one was rejected).Calling
$.when(deferreds).then(callback)leads to immediate invocation ofcallbackas mentioned before whendeferredsas an array ofDeferredobjects. Calling$.when(deferred[0], deferred[1]).then(callback)does invokecallbackwhen the aggregate state is known. Usingapplyallows you to unpack the array and use each element in the array as a parameter to the function on whichapplyis invoked (that’swhenin your case).Check your ActiveX notifications again since Firebug runs in Firefox where ActiveX is fortunately not supported. Anything related to ActiveX there is probably because you are using a Microsoft-only API which you should not do.