-1

I am retrieving a series of data from a server (geoserver) using $.ajax.

The (simplified) request looks like this:

var dataList=[];
//var urllist= // a list of several URLs to request data from


$.each(urllist,function(i) {
    $.ajax({
         jsonpCallback: 'getJson',
         type: 'GET',
         url: urllist[i],
         dataType: 'jsonp',
         success: function(data) {
                    dataList[i]=data.value;
                  }
     })
});

I need to write to the global variable dataList because I need to fire an event after all requests from urllist are finished. (I've got deferreds implemented like so).

The problem is that the finished list is always in a different order. I need the result to be in the same order as the requests.

It might be a problem of closure where the index i that is passed on to the ajax function and the allocation to dataList that is happening at a later point (when the each loop has moved on). I tried taking care of that like this but the problem remains the same. Also $.each like in the code above should create a seperate closure for every iteration anyway.

I've managed to implement a recursive function but its synchronous.

edit: suggested duplicate does not deal with looped ajax requests

Community
  • 1
  • 1
unnic
  • 101
  • 2
  • 9
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Liam Feb 09 '17 at 15:54
  • *"It might be a problem of closure where the index..."* Nope *"I've got deferreds implemented like"* uhm... no, you don't? you're missing the $.when and the return. and the deferred array. – Kevin B Feb 09 '17 at 15:54
  • 1
    I added an answer with a suggestion but now I read carefully that you want to fire an event when all requests are finished and it was not correct, so I deleted. – mrlew Feb 09 '17 at 16:23
  • @KevinB : "The (simplified) request looks like this:". I left out parts of the code intentionally to keep the post short. Check the link i provided. – unnic Feb 09 '17 at 18:33
  • no. your question needs to have an mcve – Kevin B Feb 09 '17 at 18:52

2 Answers2

1

You can access all the results in $.when callback in the correct order

// map an array of promises
var deferreds = urllist.map(function(url){
    // return the promise that `$.ajax` returns
    return  $.ajax({         
         url: url,
         dataType: 'jsonp'
     }).then(function(data){
         return data.value;
     })
});

$.when.apply($, deferreds).then(function(results){
    // results will be array of each `data.value` in proper order
    var datalist = results;
    // now do whatever you were doing with original datalist
    $.each(datalist....

}).fail(function(){
    // Probably want to catch failure
}).always(function(){
    // Or use always if you want to do the same thing
    // whether the call succeeds or fails
});
charlietfl
  • 170,828
  • 13
  • 121
  • 150
  • That way I just get one single value in results. That's why resorted to the global variable in the success handler. I can get a value with $.when(deferreds[0]).then(function(data){value=data}) Is there a simpler way to access the data in deferreds? – unnic Feb 10 '17 at 10:43
  • I just checked the values coming from the deferreds with the method above and the order is random again – unnic Feb 10 '17 at 10:47
  • ok thanks. I'll flag your answer as correct because apparently my problem is somwhere else. Since this is quite different from the original now and I created a new question here: http://stackoverflow.com/questions/42161566/looped-ajax-request-error-handling-and-return-order . – unnic Feb 10 '17 at 14:19
0

The problem was not related to the deferreds but to the jsonp or the related jsonpcallback required for the request. Requesting the data as json solved the problem

credits to @charlietfl for the answer over at: Looped ajax request. Error handling and return order

For anyone looking this up: You most likely have to to enable Cross-Origin Resource Sharing on geoserver to be able to access the JSON directly

Community
  • 1
  • 1
unnic
  • 101
  • 2
  • 9