0

I would like to call a function only after all of the ajax calls I am making in the $.each loop complete. What is the best way to achieve this?

function recaculateSeatingChartSeatIds()
{
var table_id = $(".seatingChartTable").attr("id");
var seat_id = 0;
$(".nameContainer").find("p").each(function()
{
        seat_id++;
        var participant_id = $(this).attr("data-part-id");
        $.ajax({
            method: 'POST',
            datatype: 'jsonp',
            url: base_url + 'users/assignToTableAndSeat/' + event_id + "/" + participant_id + "/" + table_id + "/" + seat_id
        }).done(function () {
            console.log("Participant Added");
        }).fail(function (xhr, text, error) {
            console.log(error);
        });
});
funcToCallAfterAllComplete();
}

1 Answers1

0

what if you set a flag on each p after the ajax call and then always call a function that checks to see if all p's have that flag

$(".nameContainer").find("p").each(function()
{
        seat_id++;
        var participant_id = $(this).attr("data-part-id");
        $.ajax({
            method: 'POST',
            datatype: 'jsonp',
            url: base_url + 'users/assignToTableAndSeat/' + event_id + "/" + participant_id + "/" + table_id + "/" + seat_id
        }).done(function () {
            console.log("Participant Added");
            $("p[data-part-id='"+ participant_id +"']").data('completed', 'completed');

        }).fail(function (xhr, text, error) {
            console.log(error);
        });
});
tryFuncToCallAfterAllComplete(){
    $(".nameContainer").find("p").each(function()
    {
        if($(this).data('complete') != 'completed'){
            return;
        }
    }
    funcToCallAfterAllComplete();
}
funcToCallAfterAllComplete();
}

this would allow you to still call them all at the same time, and funcToCallAfterAllComplete would only run when all ajax calls have finished

stackoverfloweth
  • 6,669
  • 5
  • 38
  • 69
  • 1
    I was writing a script to help him with Promises but in the middle of it someone marked it as duplicate and closed answers. Anyway, I think it will be a good candidate for Promise.all() – serdar.sanri Mar 17 '17 at 19:27
  • I'm not familiar with Promise, I will look into that. Thank you – stackoverfloweth Mar 17 '17 at 19:34
  • Basically, in your loop, you add new Promise(function(resolve, reject){ //when ajax is success; resolve(ajax result); //when error happens; reject(result)} ); then outside of your loop you add Promise.all(promiseArray).then( function(result){ // all worked out and returned array of results }).catch(function(result){ //at least one ajax request has failed. }) – serdar.sanri Mar 17 '17 at 19:38
  • that's very cool. I'm glad you mentioned something. Is `Promise` new to javascript? – stackoverfloweth Mar 17 '17 at 19:47
  • 1
    Not really, I mean came with HTML5. Older versions of IE still doesn't support it but there are polyfills for that. Also not just for ajax, there are some many uses of it. For instance, you can open a popup usin promise and resolve or reject per user's button click and run something else in same function etc, – serdar.sanri Mar 17 '17 at 19:49
  • 1
    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise – serdar.sanri Mar 17 '17 at 19:50
  • Tried to implement it into my webapp but it looks like it's not supported in IE10 or IE11. That's unfortunate – stackoverfloweth Mar 17 '17 at 20:41
  • It should work on IE 11, since they `claim` that it supports html5. but you can use `https://github.com/taylorhakes/promise-polyfill` for IE – serdar.sanri Mar 20 '17 at 14:04
  • I'm getting a console error that promise is not defined – stackoverfloweth Mar 20 '17 at 20:49