chiapa
chiapa

Reputation: 4412

Wait for several ajax calls to be complete, then do something

I've got this:

$("#grid tbody tr").each(function () {
    saveRow(model));
});

getAllRows();
...

The method saveRow is something like:

$.ajax(
{
    type: 'POST',
    contentType: 'application/json',
    url: "myUrl",
    data: JSON.stringify(model),
    success: function (data) {
        whatever();
    }
});

What happens is, I want to call the saveRow for each grid row that has changed and save it, and when they are all saved, call the getAllRows function.

What's currently happening is that when I call the getAllRows, not all of the saveRow's have finished causing the data to be returned half changed, half unchanged.

How do I ensure that I call the getAllRows only after the saveRow has finished for each row in the grid?

EDIT

Here's some more detail on the current implementation:

// ajax function to save individual row
function saveRow() {
    $.ajax(
    {
        type: 'POST',
        contentType: 'application/json',
        url: "myUrl",
        success: function (data) {
            whatever();
        }
    });
}

// array to store ajax functions called
var requests = [];

// function that iterates through all rows and saves them
$("#grid tbody tr").each(function () {
    // adding the ajax function call to the array
    requests.push(saveRow());
});


...

// supposedly, call getAllRows when all the saveRow ajax calls are done
$.when.apply($, requests).then(function () {
    getAllRows();
});

This is not working, the getAllRows is called before all the other ones finished

Upvotes: 0

Views: 76

Answers (3)

The_Black_Smurf
The_Black_Smurf

Reputation: 5259

The ajax function will provide you a promise object. If you pass those promises to the JQuery $.when function, it will return another promise that will resolve when every promises you've passed will resolve:

var promise1 = $.ajax({ /* your saveRow ajax */});
var promise2 = $.ajax({ /* your saveRow ajax */});

$.when(promise1, promise2).done(function(promise1, promise2) {
    getAllRows();
});

If you have multiple safeRow ajax to wait for, you can also use the apply function to provide an array of promises to the when function:

var promises = [];
promises.push($.ajax({ /* your saveRow ajax */}));
promises.push($.ajax({ /* your saveRow ajax */}));
//...

$.when.apply($, promises).done(function() {
    getAllRows();
});

Upvotes: 3

Matthew Lymer
Matthew Lymer

Reputation: 977

If async function do not work - you could try using a variable as a condition, i.e.

If you have 10 saveRows to call, let a global variable be saveRowsRun = 0. At the end of each SaveRow function set saveRownsRun++ Have the function getAllRows() run at the end of each saveRows function, but inside an if statement;

if(saveRownsRun == 10){
    getAllRows();
}

That would ensure if tries to fire after each row, but is only able to fire after the last row.

Upvotes: 0

armonge
armonge

Reputation: 3138

You could do something with promises like

var d1 = $.ajax({...});
var d2 = $.ajax({...});

$.when(d1, d2 );
.then(function() {
    ...
})

Upvotes: 0

Related Questions