David Stewart David Stewart - 1 month ago 5
Javascript Question

Wait until unknown number of $.get are completed, then refresh page

I am running a piece of javascript to run an Ajax call (returned as XML), process that XML and then do another Ajax call for each "record" found in the XML (deletes the record), then once all things have been completed, refresh the page.

This works fine but I can't get the Javascript to wait until all of the iterative Ajax calls have completed before refreshing the page.

What is the best way to wait until all of the iterative calls are completed before refreshing the page?

Any "AVMI_" variable is defined elsewhere.

var x = $.get(AVMI_childDB, { //******* INITIAL AJAX *******
act: "API_DoQuery",
query: AVMI_query,
clist: "3",
includeRids: "1"
});

x.then(function(xml1) {
console.dirxml(xml1);
$(xml1).find('record').each(function(){
var AVMI_record = $(this);
var AVMI_childRID = AVMI_record.attr("rid");
console.log(AVMI_childRID);
var y = $.get(AVMI_childDB , { //******* ITERATIVE AJAX CALL *******
act: 'API_DeleteRecord',
rid: AVMI_childRID
});
y.then(function(xml2) {
console.dirxml(xml2);
});
});
location.reload();
});

Answer

You need to collect each promise you create in your loop and then you can use $.when() to know when they are all done:

var x = $.get(AVMI_childDB, {   //******* INITIAL AJAX *******
    act: "API_DoQuery",
    query: AVMI_query, 
    clist: "3",
    includeRids: "1"
});

x.then(function(xml1) {
    console.dirxml(xml1);
    var promises = [];
    $(xml1).find('record').each(function(){
        var AVMI_record = $(this); 
        var AVMI_childRID = AVMI_record.attr("rid");
        console.log(AVMI_childRID);
        var y = $.get(AVMI_childDB , {   //******* ITERATIVE AJAX CALL ******* 
            act: 'API_DeleteRecord', 
            rid: AVMI_childRID
        }).then(function(xml2) {
            console.dirxml(xml2);
        });
        promises.push(y);
    });
    $.when.apply($, promises).then(function() {
        location.reload();
    })

});

It might be a little cleaner to use .map() and let jQuery collect the promises for you:

var x = $.get(AVMI_childDB, {   //******* INITIAL AJAX *******
    act: "API_DoQuery",
    query: AVMI_query, 
    clist: "3",
    includeRids: "1"
}).then(function(xml1) {
    console.dirxml(xml1);
    var promises = $(xml1).find('record').map(function(){
        var AVMI_record = $(this); 
        var AVMI_childRID = AVMI_record.attr("rid");
        console.log(AVMI_childRID);
        return $.get(AVMI_childDB , {   //******* ITERATIVE AJAX CALL ******* 
            act: 'API_DeleteRecord', 
            rid: AVMI_childRID
        }).then(function(xml2) {
            console.dirxml(xml2);
        });
    }).get();
    $.when.apply($, promises).then(function() {
        location.reload();
    })

});
Comments