roryok
roryok

Reputation: 9645

ignoring an Ajax fail when returning a promise?

I'm not sure how to title this, hopefully it's not too confusing. I have a piece of js code which performs a piped operation on a list of objects. It must perform a series of ajax requests in sequence, and return a result. Here's some very simplified code

var urls = [ 
    { url: "http://myurl.com/1", expected: "one" }, 
    { url: "http://myurl.com/2", expected: "two" }
];

$(document).on("click", "#runselftest", function () {
    for (var u in urls) {
        values.push(u);
        dfdNext = dfdNext.pipe(function () {
            return testUrl(values.shift());
        });
    }
    dfd.resolve();
});

testUrl = function (i) {                   
    return $.ajax({
        url: urls[i].url,
        dataType: "json"
    }).done(function (result) {
        if (result.result == urls[i].expected) {
            // yay
        }
        else {
            // aww
        }
    }).fail(function () {
        // this is causing the problem
    });
};

I want my op to continue processing even on a fail condition in ajax. However, if I return $.ajax and the first operation fails, the pipe stops. if I don't return $.ajax, but instead return a deferred promise in .always, the ops happen asynchronously. I want them to happen synchronously - in order. The second op must wait for the first to complete before it runs.

Do I need to rewrite my code or is there a simple solution?

Upvotes: 1

Views: 106

Answers (3)

iCollect.it Ltd
iCollect.it Ltd

Reputation: 93631

This is the minimum you want:

testUrl = function (i) { 
    var d = $.Deferred();                  
    $.ajax({
        url: urls[i].url,
        dataType: "json"
    }).always(function(){
       d.resolve();
    });
    return d.promise();
};

Upvotes: 0

abs
abs

Reputation: 801

It is better use a wrapper deferred object

testUrl = function (i) { 
    var d = $.Deferred();                  
    $.ajax({
        url: urls[i].url,
        dataType: "json",
        success: function(){
            d.resolve();
        },
        error: function(){
            d.reject();
        }
    });

    return d.promise();
};

you can use it like this

var deferred = test();
deferred.always(function(){
    //you can pout your coce
});

Upvotes: 1

Stephen Brickner
Stephen Brickner

Reputation: 2602

var promise1 = return $.ajax();
var promise2 = return $.ajax();

$.when(promise1, promise2).done(function(p1, p2) {
    //this will pipe them in order. If one fails it should move to the next, you just won't get any data from the failed promise
});

Upvotes: 0

Related Questions