Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to make $.when execute when one of JSON request fail

I'm using the below code to get JSON from multiple urls. However, when one of the URL failed or get 404 response the function the execute doesn't work. I read the jquery doc and I know "then" should execute no matter one of the call has failed.

var data = {};
var calls = [];
for (var i in funcs) {
    calls.push(
        $.getJSON(base_url+i,
            (function(i) {
                return function(d) {
                    data[i] = d;
                };
            }(i)) 
        )
    );
}
$.when.apply($,calls).then(function() {
    do_something(data);
}); 
like image 295
user2581550 Avatar asked Jul 29 '13 14:07

user2581550


People also ask

How do you handle JSON errors?

The most common way to handle JSON parse error is using try-catch block. If the JSON string is valid, it will return a JavaScript object. If the JSON string is invalid, it will throw a SyntaxError.

How can I see JSON errors?

The best way to find and correct errors while simultaneously saving time is to use an online tool such as JSONLint. JSONLint will check the validity of your JSON code, detect and point out line numbers of the code containing errors.


2 Answers

Take a look at always method. It will executed in both cases. For example:

$.when.apply($, calls).always(function() { 
    alert('Resolved or rejected'); 
});

In response to successful transaction, arguments are same as .done() (ie. a = data, b = jqXHR) and for failed transactions the arguments are same as .fail() (ie. a = jqXHR, b = errorThrown). (c)

like image 67
seteh Avatar answered Sep 23 '22 22:09

seteh


I read the jquery doc and I know "then" should execute no matter one of the call has failed.

Nope, the promise only gets fulfilled if all of the passed objects are fulfilled. If one of them fails, the result will get rejected.

is there a way to make do_something(data); execute no matter if it failed or not.

You could use .always:

// doSomething waits until all are fulfilled or one is rejected
$.when.apply($,calls).always(do_something);

Yet, you probably want to execute the callback when all calls are resolved (no matter if fulfilled or rejected) - like allSettled does in Q. With jQuery, you have to work around a little:

var calls = $.map(funcs, function(_, i) {
    var d = new $.Deferred;
    $.getJSON(base_url+i).done(function(r/*…*/) {
        d.resolve(i, r);
    }, function(/*…*/) {
        d.resolve();
    });
    return d.promise();
});
$.when.apply($, calls).then(function() {
    var data = {};
    for (var i=0; i<arguments.length; i++)
        data[arguments[i][0]] = arguments[i][1];
    do_something(data);
}); 
like image 36
Bergi Avatar answered Sep 26 '22 22:09

Bergi