Kim
Kim

Reputation: 5425

How to handle multiple ajax request error using Deferred?

I'm having some trouble handling multiple jquery ajax call, there are timeout error, but how do I know which request error this is?

$.when(ajaxDeferred1, ajaxDeferred2)
  .done(function(result1, result2) {})
  .fail(function(response, statusText) {
  // how do I know which(ajaxDeferred1 or ajaxDeferred2) ajax call error this is?
});

ajaxDeferred1

$.ajax({
  method: 'GET',
  url: xxx,
  timeout: 5000,
});

I know I can handle error by putting '.fail()' on each request, but is there any way handle error above way?

Going further, can I handle like this?

$.when(ajaxDeferred1, ajaxDeferred2)
  .done(function(result1, result2) {})
  .fail(function(errorForRequest1, errorForRequest2) {
  // handle error
});

EDIT:

I think I need to make my question more clear. In the above example:

$.when(ajaxDeferred1, ajaxDeferred2)
  .done(function(result1, result2) {})
  .fail(function(errorForRequest1, errorForRequest2) {
  // if all request has done, but one or more request has got error, return the error here then! 
  // So I can handle which part UI should show and which UI part I should hide due to the error!
});

I want to get 'done' result when all is done without error, and get 'error' when all is done but one or more request has encountered problem and return them all together into '.fail()'.

Upvotes: 0

Views: 1510

Answers (3)

svonjoi
svonjoi

Reputation: 99

Complete error handling using $.when with multiple requests

var request1 = $.ajax({
    url: '...',
    type: 'GET',
    data: {
        // data
    }
});

var request2 = $.ajax({
    url: '...',
    type: 'GET',
    data: {
        // data
    }
});

$.when(request1, request2)
.done(
    function(response1, response2) {

        // success response from both

        var jsonMvtoData = response1[0];
        var resp1statusCode = response1[2].status;

        var jsonTipoOperacion = response2[0];
        var resp2statusCode = response2[2].status;

})
.fail(function(){

    // One or both requests failed

    [request1, request2].forEach(function(req) {
        req.fail(function(jqXHR) {

           // if both request fails, this will execute twice
           // you can do what u want with the json responses
           // for example store all of them in an array
                
            if (jqXHR.responseText) {
                try {
                    // Parsed JSON from failed request
                    var parsedJSON = JSON.parse(jqXHR.responseText);
                  console.error("JSON from failed request:", jqXHR.responseJSON);
                } catch (e) {
                    console.error("Failed to parse JSON:", e);
                }
            }

        });
    });
});

Upvotes: 1

Frank Modica
Frank Modica

Reputation: 10516

I like @Miguel Mota's answer. But as an alternative, you are going to get your deferred object back if it fails. So you can add some data to it:

var dfd1 = jQuery.ajax({
    method: 'GET',
    url: 'some request that fails first',
    timeout: 1
});

dfd1.id = 1;

var dfd2 = jQuery.ajax({
    method: 'GET',
    url: 'some request that fails second',
    timeout: 1000
});

dfd2.id = 2;

jQuery.when(dfd1, dfd2)
    .done(function () { })
    .fail(function (request) {
        // id: 1
        console.log('id: ' + request.id);
    });

Upvotes: 1

Miguel
Miguel

Reputation: 20633

You can use .always() and within it iterate over each promise and check whether it resolved or failed.

var promises = [ajaxDeferred1, ajaxDeferred2]

$.when.apply($, promises)
  .always(function() {
    $.each(promises, function(i) {
      this.done(function(result) {
        console.log('promise', i, 'resolved');
      }).fail(function(error) {
        console.log('promise', i, 'failed');
      });
    });
  });

JSFiddle demo: https://jsfiddle.net/pr45eov1/3/

Upvotes: 2

Related Questions