What is the best way to test a feature service url and verify it is responding?

2281
6
09-08-2017 09:44 PM
mfcallahan
Occasional Contributor II

Before I load and begin querying all the feature service layers in my map that I have created with the ArcGIS JavaScript API, I would like to first verify that the service is responding.  What I'm trying to accomplish is to check if any urls are not responding, and if so, skip those feature services and allow my application to keep loading without them. What is the best/recommended way to do this?

6 Replies
RobertScheitlin__GISP
MVP Emeritus

The best way I have found is to use esriRequest to get the rest services json response or an error if the service is not available.

require([
  "esri/request", ... 
], function(esriRequest, ... ) {
  var layerUrl = "http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Demographics/ESRI_Census_USA/MapServer/la...";
  var layersRequest = esriRequest({
    url: layerUrl,
    content: { f: "json" },
    handleAs: "json",
    callbackParamName: "callback"
  });
  layersRequest.then(
    function(response) {
      console.log("Success: ", response.layers);
  }, function(error) {
      console.log("Error: ", error.message);
  });
  ...
});
mfcallahan
Occasional Contributor II

Thanks for the helpful reply - I've implemented something similar and this appears to be what I need.

0 Kudos
ThomasSolow
Occasional Contributor III

In general this is the kind of thing the JS API should handle.  That is, you should be able to add a feature service or layer(s) within a feature service, and the JS API should gracefully handle cases where the service doesn't respond.  You might get an error in your console, but everything should continue without a hitch.

That aside, if you want to check a service to see if it's responding you can fire a GET off to the service page, like Robert mentioned above.

KenBuja
MVP Esteemed Contributor

In one of my sites, I add a bunch of different services that are either tiled or dynamic services. I have an array of urls that I put into a promise and test. If the url returns a valid response, I add it either as a dynamic or tiled layer

var promises = [];
var layersToAdd = [];
array.forEach(urlList, function (layer) {    
    promises.push(testService(layer));
});

var allPromises = new all(promises); //uses "dojo/promise/all"
allPromises.then(function (response) {
    response.forEach(function (r) {
        if (r.resolution) {
            var newLayer;
            if (r.layer.type === "dynamic") {
                newLayer = new ArcGISDynamicMapServiceLayer(r.layer.url, {
                    id: r.layer.id
                });
            } else {
                 newLayer = new ArcGISTiledMapServiceLayer(r.layer.url, {
                     id: r.layer.id
                 });
            }
            layersToAdd.push(newLayer);
        }
    });
    map.addLayers(layersToAdd);
});
 
function testService(layer) {
    var deferred = new Deferred();
    var request = new XMLHttpRequest();
    try {
        request.open("get", layer.url + "?f=json");
    }
    catch (error) {
        console.error(error);
        deferred.resolve({ layer: layer, resolution: false });
        return deferred.promise;
    }
    request.onloadend = function () {
        if (this.status !== 200) {
            console.log("Could not load " + layer.name);
            deferred.resolve({ layer: layer, resolution: false });
        } else {
            var response = JSON.parse(this.response);
            if (response.error) {
                console.log("Could not load " + layer.name);
                deferred.resolve({ layer: layer, resolution: false });
            } else {
                deferred.resolve({ layer: layer, resolution: true });
            }
        }
    };
    request.send();
    return deferred.promise;
}
mfcallahan
Occasional Contributor II

Thanks for the reply, this is an interesting implementation of a testLayer() function.  I'm giving this a try in my application right now!

0 Kudos
KenBuja
MVP Esteemed Contributor

By the way, the array of urls that I pass into the function looks something like this:

[
  {
    url: "https://.../MapServer",
    id: "layerShoreZone",
    type: "dynamic",
    name: "ShoreZone Inventory"
  },
  {
    url: "https://.../MapServer",
    id: "layerAIS",
    type: "dynamic",
    name: "Human Uses: AIS"
  },
  {
    url: "https://.../MapServer",
    id: "layerParticipatory",
    type: "tiled",
    name: "Human Uses: Participatory Mapping"
  }
]‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍