1
votes

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?

3

3 Answers

1
votes

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>
1
votes

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
});
0
votes

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();
    });