1

I am retrieving a series of data from a server (geoserver) using $.ajax. I need to rerun the request when an error occurs, fire an event when everything is finished and be able to access the data in the correct order.

The request:

var dataAr=[] //Array to fill with data from server

//var urllist= // an array of URLs to request data from

var deferreds = []; // array to fill by ajax


// looped ajax request
$.each(urllist,function() {
  var url = this;
  deferreds.push(
    $.Deferred(function(deferred) { //wrap entire operation in another Deferred Object so i can rerun the request, see below
        $.ajax({
        jsonpCallback: 'getJson',
        url: url,
        dataType: 'jsonp',
        tryCount : 0,
        retryLimit : 3,
        error: function(){ // rerun the request
          this.tryCount++;
          if (this.tryCount <= this.retryLimit){
            $.ajax(this).then(function(data) {
                deferred.resolveWith(this, [data.value]);
             }).fail(function(jqXHR, textStatus, errorThrown) {
                 if (this.tryCount >= this.retryLimit) { // reject if repeated requests fail
                     deferred.rejectWith(this,[jqXHR, textStatus, errorThrown]);
                 }
               })
          }
        }
      }).then(function(data) {
          deferred.resolveWith(this, [data.value]);
        })
    }).promise()
  )
});

success and fail handler running on the full deferred array:

$.when.apply($,deferreds)
  .then(function(data){
    $.each(deferreds,function(i){ // not so pretty workaround to access all data in the deferreds, is there a better way?
      deferreds[i].then(function(data){dataAr[i]=data})
    })
    })
    .fail(function(data){

  })

This Method is implemented to be able to rerun the request and change the deferred state.

The request and return works but the $.when callback is not in the correct order and changing every time I rerun the whole code.

edit: The JSON returned from the server looks like this:

parseResponse({"type":"FeatureCollection","totalFeatures":"unknown","features":[{"type":"Feature","id":"","geometry":null,"properties":{"GRAY_INDEX":12}}],"crs":null})

As suggested here it works by adding &format_options=callback:getJson to the URL and jsonpCallback: 'getJson' to the request:

getJson({"type":"FeatureCollection","totalFeatures":"unknown","features":[{"type":"Feature","id":"","geometry":null,"properties":{"GRAY_INDEX":12}}],"crs":null})
Community
  • 1
  • 1
unnic
  • 101
  • 2
  • 9
  • 1
    Don't use the same `jsonpCallback` for all of them. `jsonp` requests are script requests not XMLHttpRequest. Let jQuery manage and track the callback name internally – charlietfl Feb 10 '17 at 14:26
  • I don't get any data back if I don't include that. I'll add more info to the question – unnic Feb 10 '17 at 14:34
  • Are you sure the ordering problem is caused by the jsonpCallback? I tried but can't find a way around it – unnic Feb 10 '17 at 15:46
  • 1
    yes probably is. Does the api require you to provide specific callback name? Alternative would be to make each request after previos one completes – charlietfl Feb 10 '17 at 17:39
  • Your comment helped me to solve the problem. Thanks a lot!! If you post it as an answer I can accept it to award you the points. I had enable Cross-Origin Resource Sharing on geoserver to be able to access json via ajax – unnic Feb 13 '17 at 13:49
  • 1
    ahhh...that is much better than using jsonp – charlietfl Feb 13 '17 at 13:50

0 Answers0