But when print console.log(balance) it doesnot provide me with valid array of balance json.
That's a weird thing of $.when
. It doesn't provide you with an array, but calls your callback with multiple arguments.
Another issue is if any one of my ajax calls in calculateApiBalances() fails it doesnot prints All Done.
Yes, because when one promise fails the whole $.when()
promise is rejected immediately, and you don't have any error handler. You'll have to catch errors individually if you want to always get an array (of possibly invalid responses). See also $.Deferred: How to detect when every promise has been executed.
What should be done in above code to achieve this.
First of all, avoid the deferred antipattern :-)
$(window).load(function() {
getApiModemList().then(calculateApiBalances).then(function() {
var balance = Array.prototype.slice.call(arguments);
console.log(balance);
console.log("All Done");
});
});
function getApiModemList() {
return $.getJSON(somurl).then(function(res) {
return res.data;
});
}
function calculateApiBalances(vendors) {
return $.when.apply($, $.map(vendors, function(v, k) {
return $.getJSON(someurl).then(null, $.when);
}));
}
EDIT by Roamer:
And here's a version of the master routine with a mechanism for summing the balances.
getApiModemList().then(calculateApiBalances).then(function() {
var sumOfBalances = Array.prototype.reduce.call(arguments, function(tot, obj) {
return tot + (+obj.balance || 0);
}, 0);
console.log(sumOfBalances);
console.log("All Done");
});
obj
is the object promised by $.getJSON(someurl)
in calculateApiBalances()
. In the case of a $.getJSON()
error, obj
will be a jqXHR object, obj.balance
will be undefined
and +obj.balance
will be NaN
, therefore default to adding zero; otherwise add obj.balance
.
If you wanted to know how many of the getJSON requests were successful and how many were unsuccessful, then there's some more code to write, but not a lot.