1

I have two ajax calls i.e.

var ajax1 = $.ajax({ url: Url1 });

var ajax2 = $.ajax({ url: Url2 });

$.when(ajax1, ajax2).then(function (response1, response2) {

});

We want to conditionally handle the failure cases for these API deferred requests:

  1. If ajax1 is success and ajax2 is success: Call WinAjax1_WinAjax2();
  2. If ajax1 is success and ajax2 fails: Call WinAjax1_LoseAjax2();
  3. If ajax1 fails and ajax2 is success: Call LoseAjax1_WinAjax2();
  4. If ajax1 fails and ajax2 fails: Call LoseAjax1_LoseAjax2();

If I put logic in .fail of respective ajax, I don't know what will the response of other ajax. If I put .fail in .when's failure, I am not able to identify which failure it is.

Could someone help how can I identify which ajax failed with multiple ajax requests once all the requests are completed?

Victor M Perez
  • 2,185
  • 3
  • 19
  • 22
Sahil Sharma
  • 3,847
  • 6
  • 48
  • 98

3 Answers3

1

jQuery deferred object has a state method. So you can use $.when and in case of fail check every deferred object's state.

var d1 = jQuery.Deferred();
var d2 = jQuery.Deferred();


$.when(d1, d2).then(function(v1, v2) {
 // do something on succes
}).fail(function() {
  console.log(d1.state()); // resolved
  console.log(d2.state()); // rejected
});

d1.resolve( "Fish" );
d2.reject( "Pizza fail" );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

EDIT: It seems that I missed your main goal. If you need to wait until all request will be done (reolved or rejected). Then $.when will not help with this as it will be rejected as soon as any of request will be rejected not waiting for others.

In this case I would recommend to count when all you request is finished. And then check their statuses.

var d1 = jQuery.Deferred();
var d2 = jQuery.Deferred();
var activeRequests = 2;

function onComplete() {
  activeRequests--;
  
  if (!activeRequests) {
    // check deferred object states here
    console.log(d1.state()); 
    console.log(d2.state());
  }
}

d1.always(onComplete);
d2.always(onComplete);

d2.reject( "Pizza fail" );
d1.resolve( "Fish" );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
AlexSkorik
  • 504
  • 5
  • 8
1

The answer is exactly the same as solution mentioned here.

var d1 = $.Deferred();
var d2 = $.Deferred();

var j1 = $.getJSON(...).complete(d1.resolve);
var j2 = $.getJSON(...).complete(d2.resolve);

$.when(d1,d2).done(function() {
     // will fire when j1 AND j2 are both resolved OR rejected
     // check j1.isResolved() and j2.isResolved() to find which failed
});
Sahil Sharma
  • 3,847
  • 6
  • 48
  • 98
0

You could explicitly call a function after either ajax call, which checks all ajax calls have succeeded. For example:

var ajax1_success = false,
    ajax1_called = false,
    ajax2_success = false,
    ajax2_called = false;

var afterAjax = function () {
    if (!(ajax1_called && ajax2_called)) {
        return;
    }

    // add conditionals here
};


var ajax1 = $.ajax({ url: Url1 })
    .success(function() {
        ajax1_success = true;
    }).always(function() {
        ajax1_called = true;
        afterAjax();
    });


var ajax2 = $.ajax({ url: Url2 })
    .success(function() {
        ajax2_success = true;
    }).always(function() {
        ajax2_called = true;
        afterAjax();
    });
simondo92
  • 36
  • 6
  • if any of the ajax request fails, control doesn't go to then block – Sahil Sharma Mar 15 '18 at 11:50
  • No. This doesn't work. "then" is not executed when either ajax fails – Sahil Sharma Mar 15 '18 at 12:18
  • Ok so call a function in the always callback which checks whether the ajax calls have been successful or not. As per the code example now – simondo92 Mar 15 '18 at 13:29
  • No, what if ajax1 is success but ajax2 is still in process, then afterAjax will be called.. and execute WinAjax1_LoseAjax2 which is not correct. As ajax2 is still not completed – Sahil Sharma Mar 15 '18 at 13:36
  • Then you can go back to using flags to indicate that the ajax functions have been called. Then when the 2nd ajax call has completed, whichever one it is, you will enter your various conditionals which fire off the relevant functions. I've edited the code again. – simondo92 Mar 15 '18 at 15:45