Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery waiting for $.each to finish

Hi I have a huge problem that's been bugging me for quite a while, most of the times I have been able to avoid it but now there is no other way. Below is a function that when executed sends a post request for every checked boxes. I need it to wait until the $.each has finished to refresh the page. I have performed tests with location.reload in the callback of each and outside of each. Out of 10 selected boxes only 7-8 are processed with the reload in the callback of $.each and 3-4 if moved after $.each (still inside the .click). I need it to wait, somehow, for $.each to finish and then refresh the page. Is there a way to do that?

$('button.moveToTable').click(function(event){
            $("input:checked").each(function(){
                $.post('/table/move-to-table',
                {orderID: $(this).val(),
                    tableID: $('#moveToTableID').val()
                },
                function(data){
                    location.reload();
                });
            });
            //location.reload();
        });
like image 543
user253530 Avatar asked Oct 13 '10 23:10

user253530


2 Answers

One simple way is to store the number of elements in a global scope and subtract them. When the last element finishes the request it will reload. Note that if some request return an error this will fail, you have to handle the error event as well subtracting the window.Remaining. Two or more clicks might corrupt this method as well.

window.Remaining = 0;
$('button.moveToTable').click(function(event){
    window.Remaining = $("input:checked").length;
    $("input:checked").each(function(){
        $.post('/table/move-to-table',
        {orderID: $(this).val(),
            tableID: $('#moveToTableID').val()
        },
        function(data){
            --window.Remaining;
            if (window.Remaining == 0)
                window.location.reload();
        });
    });
    //location.reload();
});
like image 176
BrunoLM Avatar answered Sep 20 '22 17:09

BrunoLM


Not sure if this is the best solution, but one idea would be to increment a count of the requests sent for each one, then decrement it as the requests return.

Use the count as a flag to determine if the reload() should fire.

Something like this:

var count = 0;

$('button.moveToTable').click(function(event){
            $("input:checked").each(function() { 
                count++; // Increment the counter for each request

                $.post('/table/move-to-table',
                {orderID: $(this).val(),
                    tableID: $('#moveToTableID').val()
                },
                function(data) { 
                    count--; // Decrement as the requests return

                        // Only reload if the count is 0
                    if( count === 0 )
                        location.reload();
                });
            });
        });

You should probably have some code to prevent the click from occurring from a second click. You could probably use the same count variable for that.

As in:

if( count === 0 ) { 
    $("input:checked").each(func...

Or a better idea may be to use this solution from nsw1475 and send only one request for all the checkboxes if that option is available to you.

like image 40
user113716 Avatar answered Sep 18 '22 17:09

user113716