5

I have the following scenario in my javascript:

  1. Ajax loads a record.
  2. Based on the return value of that record, another ajax call grabs a html form that is added into the DOM
  3. When #2 is complete, the records that were obtained from #1 are then loaded into the form created in #2.

I am using the when so that when #2 is complete, I can load the form values from #1. The problem is, is that it appears that when doesn't wait for the success handler to finish, only the ajax call itself. I need to wait for the success function of #2 to complete (as this is what created the form in the DOM) before I can continue with loading the form with values.

If I add an alert1 at step #2, it works (which I'm guessing is because it is waiting for the alert to be clicked, and in that time, the success handler has finished.

code-jaff
  • 9,230
  • 4
  • 35
  • 56
Lock
  • 5,422
  • 14
  • 66
  • 113

4 Answers4

3

Do something like this where you use nested functions in the success callback:

$.ajax({
    url: "somewhere"
    success: function(data1){
        //Use data1 to determine ajax request #2
        $.ajax({
            url: "somewhere else"
            success: function(data2){
                //Do stuff with data1 and data2
             }
         });
      }
});
winhowes
  • 7,845
  • 5
  • 28
  • 39
  • 1
    This defeats the purpose of asynchronously. You are making a request after the previous one returns. – Jose Rui Santos Feb 25 '15 at 12:18
  • Thanks. That actually does work, however I've got my second ajax inside of a function (as I use it in multiple places), so `data` will not be available. Unless I pass it as an optional param.? – Lock Feb 25 '15 at 12:19
  • @Jose Rui Santos No... the second request can't be made without info from the first (as the question states). It still makes sense to do this asynchronously as other JS on the page can continue to run (to do stuff like handle UI) without being blocked by these calls – winhowes Feb 25 '15 at 12:20
  • @Lock yeah, pass the data in as an optional param :) – winhowes Feb 25 '15 at 12:20
  • @winhowes my bad. I overlooked the question – Jose Rui Santos Feb 25 '15 at 12:22
1

You can use jQuery promises, i.e.:

var loadingData = $.get(loadDataUrl);
var loadingHtml = $.get(grabHtmlUrl);
$.when(loadingData, loadingHtml).done(function(loadDataResult, loadHtmlResult){
     //add the html to the dom
     //use data to update the dom as you please       
});

Note: $.get is just a version of $.ajax that performs a get request

Sources: http://api.jquery.com/deferred.promise/

http://api.jquery.com/jquery.get/

http://api.jquery.com/jquery.ajax/

http://api.jquery.com/jquery.when/

Rui
  • 4,847
  • 3
  • 29
  • 35
1

You should use when or success not both. It sounds like (although code samples would make this clearer) you are attaching two separate listeners to the ajax call, but you only want one to execute after the other.
I'd either roll both into one event like:

$.ajax( ... , function(){
    // success
    // prep stuff here
    $.ajax( ... , function(){
        // second success
        // do final stuff here
    });
});

Or wrap you ajax call inside another promise (this may require a bit more reading around jQuery promises).

But if you do something like

$.when($.ajax( ... , function(){
    // thing a
}).then(function(){
    // thing b
});

Thing a and b will execute at the same time, because they are designed for pretty much the same thing.

Ben
  • 1,767
  • 16
  • 32
  • 1
    since `$.ajax()` returns a promise, you don't necessarily need to wrap it into `$.when`. `$.ajax().then(function(){})` would be fine enough. – code-jaff Feb 25 '15 at 16:48
  • Very true, but as the question specifically mentioned `when` I thought I'd add it it. – Ben Feb 26 '15 at 16:42
0

Bit late to answer, but

Much better way is to use promises as the way they designed to be used

Pseudo implementation

var promise = $.ajax({
    url: url,
    data: data
}).done(function (data) {
    var result = process(data);
    return $.ajax({
        url: url,
        data: result
    });
}).done(function (data) {
    // data is the result of second ajax call
});
Community
  • 1
  • 1
code-jaff
  • 9,230
  • 4
  • 35
  • 56