I m executing identify task on multiple services,thus getting results of all services, i want to combine all results to show in a infowindow.
map.on('click',function(event){
var identify_result=[];
var resultDef=[];
var callback_counter=0;
var deferred;
var counter_res=0;
map.setCursor("Default");
if(viewData_clicked){
var def = new dojo.Deferred();
dojo.forEach(layerInfo,function(id){
var url = map.getLayer(id).url;
identifyTask = new IdentifyTask(url);
identifyParams = new IdentifyParameters();
identifyParams.tolerance=10;
identifyParams.returnGeometry = true;
identifyParams.layerIds = map.getLayer(id).visibleLayers;
identifyParams.layerOption = IdentifyParameters.LAYER_OPTION_VISIBLE;
identifyParams.width = map.width;
identifyParams.height = map.height;
identifyParams.geometry = event.mapPoint;
identifyParams.mapExtent = map.extent;
deferred = identifyTask
//identifyTask
.execute(identifyParams)
.addCallback(function (response) {
console.log("response",response);
return arrayUtils.map(response, function (result) {
var feature = result.feature;
var layerName = result.layerName;
// map.infoWindow.setTitle(layerName);
var content = "<tr bgcolor='grey'><th><b>Field Name</b></th><th><b>Value</b></th></tr>";
$.each(feature.attributes,function (key,value){
content +="<tr><td>"+ key+"</td><td><b>"+value+"</b></td></tr>";
});
// map.infoWindow.setContent("<table border='1'>"+content+"</table>");
var infotemplate = new InfoTemplate(layerName,"<table border='1'>"+content+"</table>");
feature.setInfoTemplate(infotemplate);
return feature;
});
});//execute
callback_counter++;
identify_result.push(deferred);
}); //forEach
//if(layerInfo.length === callback_counter){
//var def = identifyTask.execute();
var res_features=[];
dojo.require("dojo.promise.all");
dojo.forEach(identify_result,function(i){
counter_res++;
var def = dojo.promise.all()
def.then(function(result) {
//res=result;
dojo.forEach(result,function(element){
dojo.forEach(element,function(j){
res_features.push(j);
});
});
if((identify_result.length === counter_res) && (res_features.length > 0) ){
console.log("identify_result.length",identify_result.length);
console.log("counter_res",counter_res);
console.log("result",result);
console.log("res_features",res_features);
var defrd = new dojo.Deferred();
defrd = deferred;
defrd.results=res_features;
console.log(defrd);
//map.infoWindow.setFeatures([defrd]);
//map.infoWindow.show(event.mapPoint);
}
});
});
Here's an example that uses dojo/promise/all. This also contains extra code to identify which service the results are coming from
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!--The viewport meta tag is used to improve the presentation and behavior of the samples
on iOS devices-->
<meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no">
<title>Identify with Popup</title>
<link rel="stylesheet" href="http://js.arcgis.com/3.8/js/esri/css/esri.css">
<style>
html, body, #map {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
</style>
<script>var dojoConfig = { parseOnLoad: true };</script>
<script src="http://js.arcgis.com/3.8/"></script>
<script>
var map;
var identifyTask, identifyParams, idPoint;
var identifyResults;
require([
"esri/map", "esri/dijit/Popup", "dojo/promise/all", "dojo/domReady!"
], function (
Map, Popup, All
) {
var popup = new Popup({
fillSymbol: new esri.symbol.SimpleFillSymbol(esri.symbol.SimpleFillSymbol.STYLE_SOLID, new esri.symbol.SimpleLineSymbol(esri.symbol.SimpleLineSymbol.STYLE_SOLID, new dojo.Color([255, 0, 0]), 2), new dojo.Color([255, 255, 0, 0.25]))
}, dojo.create("div"));
map = new Map("map", {
basemap: "satellite",
center: [-83.275, 42.573],
zoom: 18,
infoWindow: popup
});
dojo.connect(map, "onLoad", mapReady);
var landBaseLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver3.arcgisonline.com/ArcGIS/rest/services/BloomfieldHillsMichigan/Parcels/MapServer", { opacity: .55 });
map.addLayer(landBaseLayer);
var militaryLayer = new esri.layers.ArcGISDynamicMapServiceLayer("http://sampleserver6.arcgisonline.com/arcgis/rest/services/Military/MapServer", { opacity: .55 });
map.addLayer(militaryLayer);
function mapReady(map) {
dojo.connect(map, "onClick", runIdentifies);
}
function runIdentifies(evt) {
identifyResults = [];
idPoint = evt.mapPoint;
var layers = dojo.map(map.layerIds, function (layerId) {
return map.getLayer(layerId);
});
layers = dojo.filter(layers, function (layer) {
if (layer.visibleLayers[0] !== -1) {
return layer.getImageUrl && layer.visible
}
}); //Only dynamic layers have the getImageUrl function. Filter so you only query visible dynamic layers
var tasks = dojo.map(layers, function (layer) {
return new esri.tasks.IdentifyTask(layer.url);
}); //map each visible dynamic layer to a new identify task, using the layer url
var defTasks = dojo.map(tasks, function (task) {
return new dojo.Deferred();
}); //map each identify task to a new dojo.Deferred
var params = createIdentifyParams(layers, evt);
var promises = [];
for (i = 0; i < tasks.length; i++) {
promises.push(tasks.execute(params)); //Execute each task
}
var allPromises = new All(promises);
allPromises.then(function (r) { showIdentifyResults(r, tasks); });
}
function showIdentifyResults(r, tasks) {
var results = [];
var taskUrls = [];
r = dojo.filter(r, function (result) {
return r[0];
});
for (i = 0; i < r.length; i++) {
results = results.concat(r);
for (j = 0; j < r.length; j++) {
taskUrls = taskUrls.concat(tasks.url);
}
}
results = dojo.map(results, function (result, index) {
var feature = result.feature;
var layerName = result.layerName;
var serviceUrl = taskUrls[index];
feature.attributes.layerName = result.layerName;
var template = new esri.InfoTemplate("", "Service Url: " + serviceUrl + "<br/><br/>Layer name: " + result.layerName + "<br/><br/> Object Id: ${OBJECTID}");
feature.setInfoTemplate(template);
var resultGeometry = feature.geometry;
var resultType = resultGeometry.type;
return feature;
});
if (results.length === 0) {
map.infoWindow.clearFeatures();
} else {
map.infoWindow.setFeatures(results);
}
map.infoWindow.show(idPoint);
return results;
}
function createIdentifyParams(layers, evt) {
var identifyParamsList = [];
identifyParamsList.length = 0;
dojo.forEach(layers, function (layer) {
var idParams = new esri.tasks.IdentifyParameters();
idParams.width = map.width;
idParams.height = map.height;
idParams.geometry = evt.mapPoint;
idParams.mapExtent = map.extent;
idParams.layerOption = esri.tasks.IdentifyParameters.LAYER_OPTION_VISIBLE;
var visLayers = layer.visibleLayers;
if (visLayers !== -1) {
var subLayers = [];
for (var i = 0; i < layer.layerInfos.length; i++) {
if (layer.layerInfos.subLayerIds == null)
subLayers.push(layer.layerInfos.id);
}
idParams.layerIds = subLayers;
} else {
idParams.layerIds = [];
}
idParams.tolerance = 3;
idParams.returnGeometry = true;
identifyParamsList.push(idParams);
});
return identifyParamsList;
}
});
</script>
</head>
<body>
<div id="map"></div>
</body>
</html>
You can run each Identify individually and append their results to your infoWindow, so no need to synchronize. I haven't tested as a whole, key part on line 12:
function handleIdentify(/*IdentifyResult*/ results){
var features = [];
// deal with results, set up templates, etc.
// . . .
// populate features as required
// Get the features currently in your infoWindow
var existingFeatures = map.infoWindow.features || [];
// Append the latest result set
map.infoWindow.setFeatures(existingFeatures.concat(features)); // <-- key part
}
function handleErrror(err){
// . . .
}
// Your many service URLs
var serviceUrls = [
];
// for each URL
for(n in services){
// create a new task
var identify = new IdentifyTask(serviceUrls
); // set the params as needed
var identifyParams = new IdentifyParameters();
// Execute the task
identify.execute(identifyParams, handleIdentify, handleError);
}
map.infoWindow.show(somePoint);