Sean Anderson
Sean Anderson

Reputation: 29301

Is it possible to use jQuery's .when() with a forEach loop of ajax calls?

I have several forms I would like to post to my server at once. Then, I want to listen for all of them to complete. If I hear them all complete successfully, I will take one action and, if I see one fail, I will take a different action.

I believe I should use jQuery's .when(): http://api.jquery.com/jQuery.when/

This post on StackOverflow shows an example on how to do it when you have all of your ajaxRequests explicitly defined: Wait until all jQuery Ajax requests are done? I am wondering if it is possible to achieve the same effect with a loop somehow?

I currently have this code, but it does not wait for all to complete:

_.each($('form'), function (form) {
            var $form = $(form);

            if ($form.valid()) {
                //  Post form data
                $.ajax({
                    url: $form.attr('action'),
                    type: $form.attr('method'),
                    data: getFormData($form),
                    success: function () {}
                    error: function(){}
                });
            }
        });

EDIT: While I've accepted an answer.. it is worth noting that the correct 'answer' was changing the design requirements. We realized that it would be extremely difficult to undo one transaction if another failed, but we had to keep all the transactions in the same state. This led us down the path that Beetroot had suggested, creating one giant model, but that added a ton of other complexities. As such, we now just have the user save before changing between tabs.

Upvotes: 1

Views: 191

Answers (1)

Matt
Matt

Reputation: 75317

You can use jQuery.when like so;

jQuery.when.apply(jQuery, $('form').map(function () {
    var $form = $(form);

    if ($form.valid()) {
        //  Post form data
        $.ajax({
            url: $form.attr('action'),
            type: $form.attr('method'),
            data: getFormData($form),
            success: function () {}
            error: function () {}
        });
    }

    // Otherwise don't do anything.
})).done(function (form1Ajax, form2Ajax, formNAjax) {
    // All complete    
}).fail(function (form1Ajax, form2Ajax, formNAjax) {
    // One failed
});

Unfortunately, jQuery.when expects each Deferred to be given as a separate parameter, rather than an array of Deferreds; which is why we're jumping through hoops with apply.

Note also the behaviour of map(); it does not add an element to the resultant array if undefined or null is returned.

Upvotes: 1

Related Questions