1

I have series of ajax calls, I want that when the calls get completed the page reloads , I am doing this

function verifyFrnds() {
    var boxes = $(".matchFrnds:checked").length;
    //alert(boxes);
    var call = 1;
    $(".matchFrnds").each(function (index) {
        if ($(this).is(':checked')) {
            call++;
            var sendData = $(this).val();
            $.post('AJAX PAGE', {
                sendData: sendData
            }, function (data) {
                //window.location.reload();
            });
            //alert(call);
            //alert(call + ' ' + boxes + ' ' + (call >= boxes));
            if (call >= boxes) {
                // window.location.reload();
                alert("I am executed");
            }
        }
    });
}

so If I do alert, then all the ajax calls are exexuted and I am shown an alert message, but If I do window.localtion.reload() then after few ajax calls the page get reloaded, which should be reloaded after ALL calls. My main purpose is to reload the page when all calls are done.Any idea what I am doing wrong. There is already a question on SO but it didn't help me much.

Community
  • 1
  • 1
  • jQuery`when` and `then` http://api.jquery.com/deferred.then/ http://api.jquery.com/jQuery.when/ – Gaurav Bhor Dec 01 '13 at 12:51
  • Something to note -- Ajax calls are Asynchronous, which means they perform independently of any other process. This means that if you're looking to sequentially call Ajax, you'll have to use a callback – Richard Peck Dec 01 '13 at 13:16

4 Answers4

1

Try using $.when:

function verifyFrnds() {
    var deferreds = []; //using an array to save promise interfaces
    $(".matchFrnds").each(function (index) {
        if ($(this).is(':checked')) {
            var sendData = this.value;
            //we push each request in array (returned promise interface)
            deferreds.push($.post('AJAX PAGE', {
                sendData: sendData
            }));
        }
    });
    //as $.when only accept deferred(promise) as arguments, we need to apply $.when to each promise of array
    $.when.apply(null, deferreds).done(function () {
        alert("I am executed once all requests done (success)");
        window.location.reload();
    });
}
A. Wolff
  • 74,033
  • 9
  • 94
  • 155
  • Although this is the best solution to the problem it makes absolutely no sense without any explanation. – m90 Dec 01 '13 at 13:03
  • @A Wolff very strange behavious, sometime it execute all the ajax cals and some time execute very few.. –  Dec 01 '13 at 16:35
  • Check your network tab for rejected requests (maybe too much parallel requests). Ideally, you should do only one request to server to send/retrieve all data at once. – A. Wolff Dec 01 '13 at 16:40
  • @A.Wolff I checked the console and it actually didn't make the request,seems like the array is not filled with correct value.. –  Dec 01 '13 at 16:47
0

You could chain your ajax call using $.then if you need to do it sequentially. Like this:

function verifyFrnds() {
    var d = jQuery.Deferred();
    var p=d.promise();

    $(".matchFrnds:checked").each(function (index) {//instead of .matchFrnds
        if ($(this).is(':checked')) {

            var sendData = $(this).val();
            p.then($.post('AJAX PAGE', {
                sendData: sendData
              }, function (data) {
                //window.location.reload();
              })
            );
        }
    });

    p.then(function(){
         alert("I am executed");
    });
    d.resolve();
}

Note that for jQuery prior to 1.8, you have to use .pipe instead of .then. Also check your code, I think there is a mistake, it should be $(".matchFrnds:checked").each( instead of $(".matchFrnds").each(

Khanh TO
  • 48,509
  • 13
  • 99
  • 115
0

Just like A. Wolff said, use jQuery.when and jQuery.then.

Another alternative is: call a method on ajax finish ( jqXHR method always ) . Check if call >= boxes ( or whatever condition you like ) in that method. For me, this is a bit easy to understand as compared to another solution.

function verifyFrnds() {
    var boxes = $(".matchFrnds:checked").length;
    //alert(boxes);
    var call = 1;
    $(".matchFrnds").each(function (index) {
        if ($(this).is(':checked')) {
            //call++; Move it to .always Thanks for pointing out Khanh
            var sendData = $(this).val();
            $.post('AJAX PAGE', {
                sendData: sendData
            }, function (data) {
                //window.location.reload();
            }).always ( function() {  
                // This method will be called on ajax completion. be it a failure or success.
                // see .done ( for success only )  ; .fail ( for failure only )
                call++;
                if (call >= boxes) {
                  // window.location.reload();
                   alert("I am executed");
                }
            }   ;


        }
    });
}

For more on jqXHR object. Read: http://api.jquery.com/jQuery.ajax/#jqXHR

Rakesh Juyal
  • 35,919
  • 68
  • 173
  • 214
  • same issue, it executed 7 calls out of 42 and reload the page –  Dec 01 '13 at 16:21
  • @user1765876: try putting `call++;` inside `.always` before `if (call >= boxes) {` – Khanh TO Dec 02 '13 at 03:39
  • @user1765876: there is a mistake in the function. I think, It should be `$(".matchFrnds:checked").each` instead of `$(".matchFrnds").each` – Khanh TO Dec 07 '13 at 01:31
-1

You should increment call not after the if, but in the success of your ajax calls.

I advice you to put the reload call in a function you call with setInterval and not in the success ajax returns.

vekah
  • 980
  • 3
  • 13
  • 31