Coron3r
Coron3r

Reputation: 79

jQuery Ajax: Wait until the first call ends, send another request $.Deferrent

I am facing an issue with Deferrent and how to use it in this specific case.

The scenario is following.

I have a loop where I am sending some data to a server. For instance:

var array = [{"effect":"save","params":["login_0_form_form_login"],"url":"http://www.example.local/login"},{"effect":"redirect","params":["index"],"url":"http://www.example.local/index"}];

$.each(array,function(key,payload) {

 $.post(payload.url,payload);

});

Then a success method which handles the result from the ajax call.

App.success = function(result){
   //Here I am deciding what to do with the result and checking for errors or warnings

   if(result.notification.success) {
      //Everything is good
   }
   else if(result.notification.error) {
      //Something is wrong, somehow stop the other ajax call  
   }
}

Nonetheless, the issue I am facing is, that the server can return an error, for example, bad login data. In this scenario, despite the bad login data returne from the server, it would redirect. I need to somehow control whether the previous request returned an error. If yes, do not follow with posting.

I tried to return a $.post within a $.when function and by using $.then. But I did not achieve what I was hoping for.

Upvotes: 1

Views: 390

Answers (1)

Alnitak
Alnitak

Reputation: 339916

You shouldn't use a loop - the AJAX calls will all start immediately (in parallel) rather than running one at a time.

I would use a recursive callback loop to process each action in turn, combined with a separate $.Deferred object to allow you to be notified what happened:

function processActions(actions) {
    var def = $.Deferred();

    (function nextAction() {
        var action = actions.shift();  // dequeue the next action
        if (action) {
            $.ajax(...).done(nextAction).fail(function() {
                def.reject();  // there was an error
            });
        } else {
            def.resolve();     // all done
        }
    })();  // invoke this function immediately

    return def.promise();
}

Upvotes: 2

Related Questions