0

I'm trying to send data off with data from multiple other Ajax requests. The issues comes when sendDataOffAjax() is called, no actual data was sent, because it fires off before any of the other functions have a change to add data. I could easily fix this by just using asyn: false everywhere, but from what I read, that's bad practice.

Here is my code:

let requests = [];
$.ajax({
    url: someUrl,
    method: 'GET',
    dataType: 'json',
    complete: function (data) {
        if (data.exists) {
            if (condition) {
                requests.push(anotherAjax());
            }
            if (condition) {
                requests.push(someDifferentAjax());
            }
        }
        requests.push(alwaysRunAjax());
    }
}).done(function () {
    $.when.apply($, requests).done(function () {
        sendDataOffAjax();
    });
});

Heres what anotherAjax() looks like (All the other Ajax requests also look like this):

function anotherAjax() {
    return $.ajax({
        url: someUrl,
        headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        },
        method: 'GET',
        dataType: 'json',
        complete: function (data) {
            if (data.exists) {
                toSendData.data['NEW_DATA'] = {
                    'data': data.responseJSON
                }
            }
            //send complete signal?
        }
    })
}

How could I make it wait until all the data is added through the other Ajax requests, then launch sendDataOffAjax().

The log looks like this:

Data sent
anotherAjax Data added
alwaysRunAjax Data added
someDifferentAjax Data added
Malpp
  • 5
  • 5

2 Answers2

0

When it comes to ajax requests, .complete(), according to jQuery's docs, runs only after the success or error callback is run and .done() is the same as calling .success(). So with this in mind you can see why the code in your done callback is running first. You should be able to switch the code from your complete callback to your done callback and vice-versa to get the desired effect.

So Try:

let requests = [];
$.ajax({
  url: someUrl,
  method: 'GET',
  dataType: 'json',
  complete: function () {
    $.when.apply($, requests).done(function () {
      sendDataOffAjax();
    });
  }
}).done(function (data) {
  if (data) {
    if (condition) {
      requests.push(anotherAjax());
    }
    if (condition) {
      requests.push(someDifferentAjax());
    }
 }
 requests.push(alwaysRunAjax());
});

Now, as long as all of your ajax functions you are calling here return deferred objects your requests array should be filled and $.when() should wait until all the deferred objects resolve.

Nathan Lynch
  • 455
  • 3
  • 11
-3

No this isn't possible without async:false. The reason it doesn't count as a good thing to use is becuase it is against the idea of a Ajax which is Asynchronous. async:false baisiclly "lock" your application to the user until your request is done and when you put it on too much ajax calls in the same time it will make your apllication seems very very slow. In your case you it will be fine if you'll use async:false on the 2 functions as long as they don't take long to execute.

Yonathanb
  • 57
  • 10
  • I mentioned `async: false` simply to say I didn't want to use it. I knew I could make it work with it. – Malpp Jul 07 '17 at 14:00