user2517737
user2517737

Reputation: 39

Execute code after all the promises have been resolved with Jquery

I seem to struggle to find out how to use the when function in my code. What I wish to achieve is a window.location.reload when all the ajax requests are done.

If I put the window.location.reload after the "each" loop then all my AJAX requests are just aborted.

$('.removeSelected').click(function() {        
    if (confirm('Are you sure you will continue?')) {
        $('.container-fluid :input:checked').each(function () {
            var recordId = $(this).data("id");
            // Jquery remove it         
            $.ajax({
                method: "GET",
                url: "/controllers/lines.asp",
                data: { recordId: recordId  }
            }).done(function() {
                console.log('done');
            });
        });
        // window location reload here
    }       
});

Upvotes: 0

Views: 161

Answers (4)

Emanuele Spatola
Emanuele Spatola

Reputation: 565

You need to pass all the promises to "when" so that it can wait for all of them to be resolved.

To do that you can put all the promises returned by $.ajax in an array and pass it to $.when:

 $('.removeSelected').click(function() {        
    if (confirm('Are you sure you will continue?')) {

    var promises = [];

    $('.container-fluid :input:checked').each(function () {

        var recordId = $(this).data("id");
        // Jquery remove it         
          promises.push($.ajax({
                method: "GET",
                url: "/controllers/lines.asp",
                data: { recordId: recordId  }
            })
                .done(function() {
                   console.log('done');

        }));

    });
    // use apply to pass an array instead list of parameters
    $.when.apply($, promises).then(function() {
        // all the promises have been resolved
        window.location.reload();
    }       
});

Upvotes: 0

Gonzalo
Gonzalo

Reputation: 992

I agree with fauxserious that sending all at once instead of making a request per record would be more efficient.

However, if for any reason you don't want to change your server side code, what you need to do is identify when all requests have been completed. You can achieve this using promises.

If you don't have much experience with this, code below should give you an idea on how to achieve the expected behavior without using promises:

$('.removeSelected').click(function() {        
    if (confirm('Are you sure you will continue?')) {

        var $containerFluidElements = $('.container-fluid :input:checked');
        var numberOfRequestsPending = $containerFluidElements.length;

        $containerFluidElements.each(function () {
            var recordId = $(this).data("id");
            $.ajax({
                method: "GET",
                url: "/controllers/lines.asp",
                data: { recordId: recordId  }
            }).done(function() {
                numberOfRequestsPending -= 1;
                if(numberOfRequestsPending == 0) 
                {
                    window.location.reload();
                }
            });
        });
    }       
});

Upvotes: 0

Donnie D'Amato
Donnie D'Amato

Reputation: 3940

The order of your logic seems to be flawed. What I think you want to do is collect all of your records and then send in one request. When the request is done, then you reload.

$('.removeSelected').click(function() {        
    if (confirm('Are you sure you will continue?')) {

        //prepare an array for records
        var records = [];

        $('.container-fluid input:checked').each(function () {
           //add the id
           records.push($(this).data("id"));
        });

        //make the request
        $.ajax({
            method: "GET",
            url: "/controllers/lines.asp",
            data: records
            }).done(function() {
               //when successful, reload the page
               window.location.reload();
            });
        });
    };
});

I'm not sure if you want to reload just on success or on complete (which will reload on fail also).

Upvotes: 1

downeyt
downeyt

Reputation: 1306

Get the number of elements to delete with

$('.container-fluid :input:checked').size();

Each time done is called, increment a separate total. When the total matches the count, reload the page.

Upvotes: 0

Related Questions