IdentifyTask with multiple map services

831
3
Jump to solution
03-19-2013 01:04 PM
DougCollins
Occasional Contributor
I am trying to figure out what is the best way to go about using the IdentifyTask with multiple map services.  All the map services are on the same ArcGIS Server instance, but I have several map services that need to have identify capability.

Is there a best practice that people are using to make this work?  Seems like this is a "common" requirement, but I did not see anything in the docs that talk about it.

Thanks,
Charlie
0 Kudos
1 Solution

Accepted Solutions
DianaBenedict
Occasional Contributor III
In a nutshell you will probably want to loop through an array of IdentifyTasks that each point to your repective services and properties.

Once you have your array built up or something similar then you might want to look at Dojo.DeferredList of more current implementation of Dojo.PromiseAll.  Note that the IdentifyTask.execute return a Dojo.Deferred object this is key in being able to use the methods mentioned above.

The DeferredList allows you to make asynch calls to the server simultaneously and it will wait until the excute tasks have all finished. Below is some sample code that uses the DeferredList to execute select statements to the server simulateously. In your case, you would build your DeferredList (or better PromiseAll) of dojo.deferred array objects and them make the request to the server (identifyTask.execute()) and wait until the calls have finished (dl.then ..) .  The within the deferredList.then is used to build up the results that are returned and then turn the values back in some kind of order that makes sense to you and your application. In my example below, I return a custom object "selectionLayers" that I need for processing (returnDeferred.resolve({ 'success': true, 'selectionLayers': selectionLayers }) )

I am sure there are other ways to do this, but so far without having to create a custom service that does all this for me, I have found this to work for me when I am making multiple simultaneous requests to the server - if a deferred object is returned from the Javascript API.  Good Luck!

//sample code - not for production //should consider using Promise and PromiseAll function getSelectionLayerDeferred(featureLayerArray, selectQuery) {   var returnDeferred = null;   var selectionLayers = [];   var defferredCallArray = [];    require(["dojo/DeferredList", "dojo/Deferred"], function (DeferredList, Deferred) {     returnDeferred = new Deferred();      dojo.forEach(featureLayerArray, function (flayer) {       var defferredCall = flayer.selectFeatures(selectQuery, esri.layers.FeatureLayer.SELECTION_NEW);       //cast the dojo.deferred to a promise so we can use the new        //dojo/promise/all in lieu of dojo/DeferredList (deprecated at v 1.8)       defferredCallArray.push(defferredCall);     });      var dl = new DeferredList(defferredCallArray);     dl.then(function (results) {       // Executed when all deferred resolved       if (results.length > 0) {         dojo.forEach(results, function (result) {           if (result[0] === true && result[1].length > 0) {             selectionLayers.push({ 'featureLayer': result[1][0].getLayer(), 'features': result[1] });           }         });       }       returnDeferred.resolve({ 'success': true, 'selectionLayers': selectionLayers });     }, function (err) {       returnDeferred.resolve({ 'success': false, 'selectionLayers': null, 'error': err });     });   });   return returnDeferred; }  //here is some sample code of how I implement it //not for production //select related records   var selQuery = new esri.tasks.Query();   selQuery.where = "GAZ_ID = " + updateGraphic.attributes["GAZ_ID"]; var deferred = getSelectionLayerDeferred([landformAllpointFeatureService], selectQuery);       deferred.then(function (results) {         if (results.success && results.selectionLayers) {           //bind to data to add to grid           //TODO: work in progress ...            //           buildDataStore(results.selectionLayers[0].features)           setDisableToolbarControls(ToolbarType.Editor_Select, false);           hideProcessingDialog();           refreshMap();         } else {           setDisableToolbarControls(ToolbarType.Editor_Select, true);           hideProcessingDialog();         } }, function (error) {     // Do something on failure.     hideProcessingDialog();     drawToolbar.deactivate();     //var err = results.error;     alert("Error ...")       });  

View solution in original post

0 Kudos
3 Replies
DianaBenedict
Occasional Contributor III
In a nutshell you will probably want to loop through an array of IdentifyTasks that each point to your repective services and properties.

Once you have your array built up or something similar then you might want to look at Dojo.DeferredList of more current implementation of Dojo.PromiseAll.  Note that the IdentifyTask.execute return a Dojo.Deferred object this is key in being able to use the methods mentioned above.

The DeferredList allows you to make asynch calls to the server simultaneously and it will wait until the excute tasks have all finished. Below is some sample code that uses the DeferredList to execute select statements to the server simulateously. In your case, you would build your DeferredList (or better PromiseAll) of dojo.deferred array objects and them make the request to the server (identifyTask.execute()) and wait until the calls have finished (dl.then ..) .  The within the deferredList.then is used to build up the results that are returned and then turn the values back in some kind of order that makes sense to you and your application. In my example below, I return a custom object "selectionLayers" that I need for processing (returnDeferred.resolve({ 'success': true, 'selectionLayers': selectionLayers }) )

I am sure there are other ways to do this, but so far without having to create a custom service that does all this for me, I have found this to work for me when I am making multiple simultaneous requests to the server - if a deferred object is returned from the Javascript API.  Good Luck!

//sample code - not for production //should consider using Promise and PromiseAll function getSelectionLayerDeferred(featureLayerArray, selectQuery) {   var returnDeferred = null;   var selectionLayers = [];   var defferredCallArray = [];    require(["dojo/DeferredList", "dojo/Deferred"], function (DeferredList, Deferred) {     returnDeferred = new Deferred();      dojo.forEach(featureLayerArray, function (flayer) {       var defferredCall = flayer.selectFeatures(selectQuery, esri.layers.FeatureLayer.SELECTION_NEW);       //cast the dojo.deferred to a promise so we can use the new        //dojo/promise/all in lieu of dojo/DeferredList (deprecated at v 1.8)       defferredCallArray.push(defferredCall);     });      var dl = new DeferredList(defferredCallArray);     dl.then(function (results) {       // Executed when all deferred resolved       if (results.length > 0) {         dojo.forEach(results, function (result) {           if (result[0] === true && result[1].length > 0) {             selectionLayers.push({ 'featureLayer': result[1][0].getLayer(), 'features': result[1] });           }         });       }       returnDeferred.resolve({ 'success': true, 'selectionLayers': selectionLayers });     }, function (err) {       returnDeferred.resolve({ 'success': false, 'selectionLayers': null, 'error': err });     });   });   return returnDeferred; }  //here is some sample code of how I implement it //not for production //select related records   var selQuery = new esri.tasks.Query();   selQuery.where = "GAZ_ID = " + updateGraphic.attributes["GAZ_ID"]; var deferred = getSelectionLayerDeferred([landformAllpointFeatureService], selectQuery);       deferred.then(function (results) {         if (results.success && results.selectionLayers) {           //bind to data to add to grid           //TODO: work in progress ...            //           buildDataStore(results.selectionLayers[0].features)           setDisableToolbarControls(ToolbarType.Editor_Select, false);           hideProcessingDialog();           refreshMap();         } else {           setDisableToolbarControls(ToolbarType.Editor_Select, true);           hideProcessingDialog();         } }, function (error) {     // Do something on failure.     hideProcessingDialog();     drawToolbar.deactivate();     //var err = results.error;     alert("Error ...")       });  
0 Kudos
deleted-user-RAnWn8DDSd1P
New Contributor III
use a bunch of dojo/Deferred's for each IdentifyTask in a dojo/DeferredList.  I think I used this example as a start: http://jsfiddle.net/blordcastillo/mULcz/
0 Kudos
DougCollins
Occasional Contributor
Thanks for replies, this helps.

Charlie
0 Kudos