Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use JQuery $.when to process ajax calls in order?

How do I use $.when in JQuery with chained promises to ensure my ajax requests are completed in the right order?

I have an array called costArray which is made up of a number of dynamic objects. For each item in this array, I'll call an Ajax request called GetWorkOrder which returns a WorkOrder which is basically a table row element with the class .workOrder and appends it to the table with id #tbodyWorkOrders.

Once all the items in the array are processed, I use $.when to let me know when I can calculate the SubTotal of each WorkOrder.

My problem is that my WorkOrders are being inserted in random orders, as the ajax requests are being processed async. How can I ensure my ajax requests are processed and appended in the correct order?

i = 0;

$.each(costArray, function (key, value) {
var d1 = $.get('/WorkOrders/GetWorkOrder', { 'i': i }, function (html) {
    $('#tbodyWorkOrders').append(html);
    $('.workOrder').last().find('input').val(value.Subtotal);
});

$.when(d1).done(function () {
    SetSubtotal();
    i++;
});

Edit:

costArray is taken from an earlier ajax call and is an array of items that I am inserting into the table rows:

var costArray = JSON.parse([{"Trade":"Plasterer","Notes":"Test","Subtotal":"3781.00"}]);

The line:

$('.workOrder').last().find('input').val(value.Subtotal);

is one of many that takes the values from GetWorkOrder and puts them into the correct inputs, but I've left out the extra code for clarity

like image 710
Evonet Avatar asked Sep 07 '15 21:09

Evonet


People also ask

Can jQuery and AJAX be used together?

jQuery provides several methods for AJAX functionality. With the jQuery AJAX methods, you can request text, HTML, XML, or JSON from a remote server using both HTTP Get and HTTP Post - And you can load the external data directly into the selected HTML elements of your web page!

Which three parameters are used in the sequence of AJAX call?

The “open” method has three parameters. The first parameter is the approach of sending HTTP request, and it has to be within GET, POST or HEAD. The second one is URL. And the third one is the sign of whether the request is to be carried out in an asynchronous mode.

How get data from AJAX call in jQuery?

ajax({ type: "POST", url: 'test. php', data: {"type":"check"}, success: function(response){ alert(response); } }); There can obviously be more key-val pairs in data. In this case your alert should read: "The type you posted is check".

What is the difference between jQuery get () and jQuery AJAX ()?

get() executes an Ajax GET request. The returned data (which can be any data) will be passed to your callback handler. $(selector). load() will execute an Ajax GET request and will set the content of the selected returned data (which should be either text or HTML).


2 Answers

$.when() processes all the promises you pass it in parallel, not sequential (since the async operations have already been started before you even get to $.when()).

It will collect the results for you in the order you pass the promises to $.when(), but there is no guarantee about the execution order of the operations passed to it.

What I would suggest is that you collect all the results (in order), then insert them in order after they are all done.

I've tried to restructure your code, but it is not clear what items form costArray you want to pass to your Ajax call. You weren't passing anything from costArray in your code, but the text of your question says you should be. So, anyway, here's a structural outline for how this could work:

var promises = costArray.map(function (value, index) {
    // Fix: you need to pass something from costArray to your ajax call here
    return $.get('/WorkOrders/GetWorkOrder', { 'i': value });
});
$.when.apply($, promises).done(function() {
    // all ajax calls are done here and are in order in the results array
    // due to the wonders of jQuery, the results of the ajax call
    // are in arguments[0][0], arguments[1][0], arguments[2][0], etc...
    for (var i = 0; i < arguments.length; i++) {
        var html = arguments[i][0];
        $('#tbodyWorkOrders').append(html);
    }
    SetSubtotal();
});
like image 88
jfriend00 Avatar answered Oct 24 '22 08:10

jfriend00


Wrap it in a function and recall it from your ajax success:

ajax(0);
function ajax(key) {
    $.get('/WorkOrders/GetWorkOrder', {'i' : key }, 
        function (html) {
            $('#tbodyWorkOrders').append(html);
            $('.workOrder').last().find('input').val(costArray[key].Subtotal);
            SetSubtotal();
            key++;
            if (key < costArray.length)
                ajax(key);
        });
}

Edit: On further consideration, while this is one way to do it, it entails the ajax calls executing only one at a time, which isn't very time efficient. I'd go with jfreind00's answer.

like image 37
Drazen Bjelovuk Avatar answered Oct 24 '22 08:10

Drazen Bjelovuk