hatchetaxesaw
hatchetaxesaw

Reputation: 183

jQuery wait for two separate AJAX calls for each iteration to complete before completing

I've been struggling all day with this and have read countless SO posts on AJAX, deferred, promises, etc.
Every time, with every change I make, it's still the same: the call to the generateLSRDetailRadiusMetrics function gets called BEFORE all of the AJAX calls are complete. :-(

Here's what I'm trying to do:

Loop through an array and for each item in the array, I need to call two (2) AJAX functions. Once all items in the array have made the two (2) AJAX calls, I then need to wait for all pending calls to complete before moving on to the next step.

The two AJAX calls: promises.push(saveLayerCBG(radiusLayerObject, false)) and promises.push(saveLayerPractices(radiusLayerObject, false)) both return promises. If I break the code, I can see that the array does indeed contain promises.

From what I'm reading (but not clearly understanding), I need to add the promises to an array and then use the $.when.apply($, promises).done syntax to evaluate the array of promises.

What am I doing wrong here?

Here's my main code:

function LSRRadiusMapProcessing(radiusMaps, newLSR, allRadiusLayers, lsrHeaderId, specialtyId) {
    return new Promise(function (resolve, reject) {
        const options = { steps: 64, units: 'miles' };
        let promises = [];
        for (let i = 0; i < radiusMaps.length; i++) { 
            promises.push(saveLayerCBG(radiusLayerObject, false));
            promises.push(saveLayerPractices(radiusLayerObject, false));
        }

        $.when.apply($, promises).done(function () {
            const lsrdetails = generateLSRDetailRadiusMetrics(lsrHeaderId, specialtyId);
            lsrdetails.then(function () {
                resolve(); 
            });
        });
    });
};

Upvotes: 0

Views: 543

Answers (1)

Carsten Massmann
Carsten Massmann

Reputation: 28196

The "subtle" differences of jQuery Deferreds to Promises can be seen below:

$.when($.get(url1),$.get(url2))
 .then(function(){console.log(arguments[0][0]+arguments[1][0]);})

With .when() you can group several deferreds into a common group. The following (jQuery-).then() will then deal with the results from all AJAX calls. The callback function in .then() should be set-up to expect as many arguments as there were deferreds in the $.when()-call. In my example I simply use the arguments iterator within the callback function to access all arguments.

// set up AJAX environment for testing:
// mirror data back as a JSON string (works only with GET):
function echoURL(data) {
  return URL.createObjectURL(new Blob([JSON.stringify(data)],{type: "text/json"}));
}
// two "URLS" returning different values (35 and 7)
const url1=echoURL(35), url2=echoURL(7);

//================================
//actual demo of jQuery deferreds:
//================================

$.when($.get(url1),$.get(url2))
 .then(function(){console.log("then:",arguments[0][0]+arguments[1][0]);})
 
 // it works just as well with .done():
 
 $.when($.get(url1),$.get(url2))
 .done(function(){console.log("done:",arguments[0][0]+arguments[1][0]);})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

Upvotes: 0

Related Questions