2

I need to count how many times a jQuery ajax call is successfully executed on each item in a list.

I started here, but then realized this won't work because of the "asynchronous" part of ajax:

var numSuccessfullUpdates = 0;

$('#saveMyListItems').click(function (event) {
    event.preventDefault();

    $('ul#myList li').each(function () {
        $.ajax({
            url: '[my_url]',
            type: "POST",
            data: {
                // [data block here, not relevant to question]
            },
            success: function () {
                numSuccessfullUpdates++;
            }
        });
    });
    if (successfullUpdates > 0){
        alert(numSuccessfullUpdates);
    }
});

Any suggestions?

Faust
  • 15,130
  • 9
  • 54
  • 111

3 Answers3

3

You can try the new when() and then() features available in jQuery 1.5+,

$.when($.ajax("/page1.php"), $.ajax("/page2.php")).then(myFunc, myFailure);

Here execute the function myFunc when both ajax requests are successful, or myFailure if either one has an error.

So, by the above function you can check if all the ajax requests were successfully completed if the myFunc function is run.

Sujit Agarwal
  • 12,348
  • 11
  • 48
  • 79
  • Awesome! The `$.when()` feature is really powerful. Thanks for telling us about it. – justis Jun 16 '11 at 07:44
  • OK, I've wrapped $('ul#myList li').each(...); inside $.when() and set up 2 functions for success and failure. Still, the alert is presenting 0. Is this a variable scope issue? – Faust Jun 16 '11 at 08:12
  • Do you really need to count the numbers? or will it be sufficient to check if all ajax requests are run or not? – Sujit Agarwal Jun 16 '11 at 08:32
2

You could use the complete handler for AJAX and count the status results until the total of results equals to the total of requests. Here is example code, also available as a jsFiddle

$('#saveMyListItems').click(function (event) {
    event.preventDefault();

    var ajaxCounter = {
        goal: $('ul#myList li').length,
        total: 0,
        success: 0,
        notmodified: 0,
        error: 0,
        timeout: 0,
        abort: 0,
        parsererror: 0
    }

    $('ul#myList li').each(function () {
        $.ajax({
            url: '/echo/html',
            type: "POST",
            timeout: 1500,
            data: {
                html: "foobar",
                delay: Math.floor(Math.random() * 5)
            },
            complete: function (jqXHR, textStatus) {
                ajaxCounter.total++
                ajaxCounter[textStatus]++;
                if (ajaxCounter.total >= ajaxCounter.goal) {
                    alert(ajaxCounter.success + ' out of ' + ajaxCounter.total);
                }
            },
        });
    });
});
justis
  • 504
  • 4
  • 6
  • Note that the random delay is so that it sometimes times out instead of succeeding. It seems that it only works on the first request, though? I'm a little new to using jsFiddle for testing AJAX. – justis Jun 16 '11 at 07:44
  • I upvoted the answer from @coding-freak about `$.when()` because it's a far more elegant solution. Since I was already mostly finished with the example above, though, I thought you might appreciate an alternate solution. – justis Jun 16 '11 at 07:46
  • Perhaps coding-freak's solution is more elegant -- and i upvoted it because it's agood thing to know -- but yours is the one I got to work. – Faust Jun 16 '11 at 08:51
0

You need to count all responses as well, and alert when the total is reached or when a sensible timeout has expired.

k_b
  • 2,470
  • 18
  • 9