0

I have a question about AJAX calls in jQuery
This is the problem I'm trying to solve:

  1. Call the server to get a list of codes
  2. For each code, call the server again to get the list of customers
  3. Display the result

I have a code snippet like this (it's almost a pseudo-code; just wanted to mention the parts of interest):

$('button#myButton').click(function() {
    var codes = [];
    var customers = [];

    $.ajax({
        // URL etc. Properties,
        async: false
    }).done(function(codes) {
        // Update the values in the 'codes'  array to be used later
    });

    // Use the 'codes' array to get the customers for each code
    //    and populate the 'customers' array
    $(codes).each(function() {
        $.ajax({
            // URL etc. Properties,
            async: false
        }).done(function(customers) {
            // Populate the 'customers' array
        });        
    });

    // Display the results (using both arrays) in a 'div'
});  

Now, here's my problem:
At first, I wanted to do this thing using 2 nested getJSON calls, but no matter how hard I tried, I couldn't make it work (the second call waited for the first call to completely finish and then started the call)

Then, searching here, I saw that someone suggested to set the async function to false and it seems that now, the calls are behaving in the same order as the code

The only thing that I don't understand is that I receive a warning about Synchronous XMLHttpRequest on the main thread is deprecated and in jQuery's website, it's mentioned to use success/error/complete methods, but if I disable the async, then the order of the calls is messed up (at least I can't understand the order) and when I reach the second call, my codes array is empty, so there's nothing to do there!!!

Any help is appreciated because I spent a whole morning trying to make it work!

PS: As I said, the code is working, and I'm merely interested in the correct way to do it

Update

Thank you all for your answers. Maybe if I mention how I am supposed to display the result, it would make things more clear
I'm trying to display the results in a table with 'code', 'rate', and then 'customers'

When I'm finished with my first AJAX call, I have the values for my first two columns, so I can added the corresponding trs (and tds), but when I reach the second AJAX call, I have to go through each code to get the 'customers' for each code (from the server)

If I put all the logic into the second AJAX call's complete method, I have all the rows WITHOUT the third column, so I need to somehow add the customers to the last td on each row, which I don't know how!!!

4
  • You have to work with the asynchronicity, making the ajax call synchronous by using async:false should never be done, and that's why the browser is telling you to stop doing it. Commented Feb 20, 2016 at 18:06
  • async:false is a terrible practice and has been deprecated by browser vendors. Commented Feb 20, 2016 at 18:12
  • Provide more detailed explanation of what the flow should be and if the secondary calls rely on needing data from first Commented Feb 20, 2016 at 18:14
  • I updated my question about how I want to display the data. Can you guys check it out and tell me your opinion? Commented Feb 20, 2016 at 20:21

2 Answers 2

1

The calls are (or at least should be) ran on the order they're in the code. However, if you remove the async: false you can never know in advance which completes first.
This is why you should use callback methods.
Personally, I would remove the async: false and call the second ajax from the success function of the first.

Sign up to request clarification or add additional context in comments.

1 Comment

I updated the question about how I want to display the data, and the problem I have If I move everything inside the second success
1

The way to solve this, is to do the first ajax call, and then in the callback of that ajax call, do the iteration and add the Deferreds of all those calls to an array.
Then, using $.when.apply you can add a callback for when all those requests are done, and get the "customers", something like this

$('button#myButton').click(function() {

    $.ajax({
        // URL etc. Properties,
    }).done(function(codes) {
        var requests = $.map(codes, function(i, code) {
            return $.ajax({
                url  : '/get_the_codes',
                data : {code : code}
            });
        });

        $.when.apply($, requests).then(function(customers) {
            $.each(customers, function(i, customer) {
                $('div').append(customer);
            });
        }, function(err) {

        })
    });
});  

A somewhat better option would be to create something serverside that does this, so only one request would be needed, where the server would get the codes, iterate and create an array of customers etc, and send them all back in one go.

2 Comments

Can you please explain a little more about your code? I'm almost new to jQuery, and I don't understand what's happening with map, or when and apply methods .... Also, I updated my question and mentioned how I need to display my data; would it affect your answer?
The map function returns an array, of whatever you return, and here the Deferred object that $.ajax returns is returned from the map, creating an array of "deferreds". jQuery's $.when can be used with multiple ajax calls, if one does $.when(ajax1, ajax2, ajax3) etc. and that's what we're doing here, only the array is passed in with .apply(), which calls a function with the arguments as an array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.