Egli Becerra Egli Becerra - 5 months ago 26
jQuery Question

Ajax API calls in nested loop need to be executed in order

lets say you have a scenario where you needed to create a .csv output in a page's textarea...

So I have 2 arrays which i loop nested within one another. The result of the nested loop is a query that is passed an ajax call... I need to append the result of the ajax call into the textarea.

My question is how do you get the results printed out in the order they are requested (basically the order in the queries array)



//example array to loop.
var outerQuery= ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery= ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;

//the textarea where im going to print the results in order later to open in excel as a .csv file
var $csvText= $('#some-text-area');

//outter loop
$.each(outerQuery, function(outerIndex, outer){
//Print the row
$csvText.append('Row' + outer +'\r\n\r\n');

//Nested inner loop (that should execute in order regarless or the time of the api call)
innerQuery.reduce(function(innerCallback, inner, innerIndex){
return innerCallback.then(function(){
return GoogleAnalyticsAPI(inner).then(function(response){
$csvText.append(response.column1 +',');
});
});//end inner callback
},Promise.resolve());
});

function GoogleAnalyticsAPI(val) {
return new Promise(function(resolve) {
setTimeout(function() {
resolve({column1: val });
}, Math.floor((Math.random() * 1000) + 1));
});
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<textarea id="some-text-area" rows="20" cols="30"></textarea>





As you can see the results in the snippet run pretty out of wack
ideally they should print like this:

RowA
1,2,3,4,5,6
RowB
1,2,3,4,5,6
RowC
1,2,3,4,5,6
.
.
.


The innerQuery.reduce i got from Ajax API calls in loop need to be executed in order which really helped thanks @jfriend00

Thanks guys

Answer

You can use .queue(), .promise() to return functions in sequential order corresponding to index within an array

//example array to loop.
var outerQuery = ['A', 'B', 'C', 'D', 'E', 'F'];
var outerQueryLegth = outerQuery.length;
var innerQuery = ['1', '2', '3', '4', '5', '6'];
var innerQueryLegth = innerQuery.length;
var $csvText = $('#some-text-area');

// create `"outerQuery"` queue
$csvText.queue("outerQuery", $.map(outerQuery, function(outer, index) {
  return function(next) {
    $(this).append((index > 0 ? '\r\n\r\n' : "") 
                    + 'Row' + outer + '\r\n\r\n')
    // create `"innerQuery"` queue
    .queue("innerQueue", $.map(innerQuery, function(inner, innerIndex) {
        return function(_next) {
          return GoogleAnalyticsAPI(inner).then(function(response) {
            $csvText.append(response.column1 + ',');
            // call `_next` function in `"innerQueue"`
          }).then(_next); 
        }
      })).dequeue("innerQueue").promise("innerQueue")
    // call `next` function in `"outerQueue"`
    // when all functions in current `innerIndex`
    // of `innerQueue` array , `"innerQueue"` completes
    .then(next)
  }
})).dequeue("outerQuery");

function GoogleAnalyticsAPI(val) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve({
        column1: val
      });
    }, Math.floor((Math.random() * 1000) + 1));
  });
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<textarea id="some-text-area" rows="20" cols="30"></textarea>