1

Below are my Multiple ajax calls with promises.

$(window).load(function(){
 $.when(getApiModemList()).done(function(vendors){

    var deferreds = calculateApiBalances(vendors);

    $.when.apply($,deferreds).done(function(balance) {
     console.log(balance);
     console.log("All Done");
    });

});


function getApiModemList(){
   return $.getJSON("url");
}

 function calculateApiBalances(vendors)
  {
   var defer=[];
   $.each(vendors,function(k,v){
    defer.push($.getJSON(someurl));
   });
  return defer;
 }

 });

Function calculateApiBalances() return me some balance which I need to Sum up to get total of all balance . But when print console.log(balance) it doesnot provide me with valid array of balance json. Another issue is if any one of my ajax calls in calculateApiBalances() fails it doesnot prints All Done. What should be done in above code to achieve this.

Vibhas
  • 241
  • 5
  • 20
  • 2
    First of all, [avoid the deferred antipattern](http://stackoverflow.com/q/23803743/1048572)! – Bergi Apr 23 '15 at 07:28
  • What should the array contain in case of of an error? Usually, the joined promise is simply rejected. – Bergi Apr 23 '15 at 07:29
  • @Bergi . Fixed anitpattern issue.I dont care if some ajax call fails I only need to consider balance of successful ajax calls.Is it possible ? – Vibhas Apr 23 '15 at 07:41

1 Answers1

1

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.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • @Roamer: Ah, I missed that requirement, thanks for editing it in. However your edit is on the edge of legality, how can I upvote it? :-) – Bergi Apr 23 '15 at 13:35
  • Bergi, "edge of legality"? – Roamer-1888 Apr 23 '15 at 13:43
  • Sorry for the odd term, non-native speaker here. I meant that the edit was borderline, and would probably not have been accepted as an edit suggestion ("too drastic change", "attempt to reply"). I'm fine with it though, thank you. – Bergi Apr 23 '15 at 13:50
  • Bergi, interestingly if you are logged out of SO (or get the RSS feed in email client), the "edit" link reads "improve this answer", which appears to invite edits of this kind. BTW, I have always assumed English was your first language :-) – Roamer-1888 Apr 23 '15 at 16:37
  • Oh thank you. Yeah, I don't mind such edits, and do them myself sometimes, but I just haven't seen them commonly – Bergi Apr 23 '15 at 17:30