Reputation: 399
I'm working on a project where inside a loop I need to make multiple JSON calls. As soon as I exit that loop I need to work with the results of all the calls I made. I'm having a hard time understanding how to make these calls in such a way that my order of operation works out. My code to work with the results always executes before the calls to the service have completed. I created a jsfiddle to demonstrate and am including the code here.
var sourceData = { "fooIndex": "foo",
"barIndex": "bar"
}
var destinationData = {};
for (var sourceIndex in sourceData) {
$.getJSON('http://echo.jsontest.com/' + sourceIndex + '/' + sourceData[sourceIndex] + '?callback=?', null, function (result) {
for (var resultIndex in result) {
alert("Adding " + resultIndex + " : " + result[resultIndex]);
destinationData[resultIndex] = result[resultIndex];
}
});
}
if (Object.keys(destinationData).length == 0) {
alert("Destination not yet populated");
}
else {
alert("Eureka! You did it!");
}
Upvotes: 2
Views: 1281
Reputation: 227270
This looks like a job for jQuery Deferred Object, and my sidekick $.when
!
Pass all the $.getJSON
calls to $.when
, and when they are all done, I'll will call a function with all the results.
Check this out:
var sourceData = {
"fooIndex": "foo",
"barIndex": "bar"
};
var destinationData = {};
// Array of AJAX calls
var AJAX = [];
for (var sourceIndex in sourceData) {
AJAX.push($.getJSON('http://echo.jsontest.com/' + sourceIndex + '/' + sourceData[sourceIndex] + '?callback=?'));
}
// Apply is needed to pass each element as a parameter
$.when.apply($, AJAX).done(function(){
// This function will be called when all the AJAX calls are done
// The arguments of the functin are the responses from each request
for(var i = 0, len = AJAX.length; i < len; i++){
var result = arguments[i][0];
//arguments: [resultObj, 'success', jqXHR]
for (var resultIndex in result) {
alert("Adding " + resultIndex + " : " + result[resultIndex]);
destinationData[resultIndex] = result[resultIndex];
}
}
alert("Eureka! You did it!");
});
NOTE: Since this is asynchronous, destinationData
won't be available until the callback is triggered. Put any code that uses that inside the .done()
callback.
Upvotes: 5
Reputation: 3635
Since you are using jQuery already I suggest exploring the queue functions. You can queue the ajax calls and then in the success handlers call the de-queue or next function. this way they go in succession. The last item you add to the queue is your function that handles the returned data.
var sourceData = {
"fooIndex": "foo",
"barIndex": "bar"
};
var destinationData = {};
$(function () {
console.debug('ready');
for (var sourceIndex in sourceData) {
console.debug('for Loop');
$(document).queue('ajax', function (next) {
$.getJSON('http://echo.jsontest.com/' + sourceIndex + '/' + sourceData[sourceIndex] + '?callback=?', null, function (result) {
for (var resultIndex in result) {
alert("Adding " + resultIndex + " : " + result[resultIndex]);
destinationData[resultIndex] = result[resultIndex];
next();
}
});
});
}
$(document).queue('ajax', function (next) {
alert("Eureka! You did it!");
});
$(document).dequeue('ajax');
});
I do this all the time for 'synchronus' ajax.
here is an example of what i am talking about
Upvotes: 3