This code works with a hosted feature service:
// Define hook for Parcel Layer
var parcelLayer = map.getLayer(this._parcelLayerID);
// Define the Selected Parcels Symbol
var highlightSymbol = this._getHighlightSymbol();
// Define OnClick event for clicking on a Parcel
this.onParcelClick = on.pausable(parcelLayer, 'click', lang.hitch(function (e) {
var taxlotString = esriLang.substitute(e.graphic.attributes, "${TAXLOT}");
var ownerString = esriLang.substitute(e.graphic.attributes, "${OWNERNAME}");
if (ownerString.length > 24) ownerString = ownerString.substring(0, 24) + "...";
var attr = { "Taxlot": taxlotString };
var highlightGraphic = new Graphic(e.graphic.geometry, highlightSymbol, attr);
map.graphics.add(highlightGraphic);
}));
However when I use a map service hosted on our own AGS, it does not. I can get a reference to the parcel layer using LayerInfos, but when I click on the map...nothing. Any ideas?
Solved! Go to Solution.
Adam,
That now makes sense. Your code is flawed when it come to layers coming from a map service vs. hosted one.
Here is what should work:
_getLayerID: function _getLayerID(map, layerTitle) {
//local function to fetch the LayerID of layer in the map
var layerID;
if (this.map.itemId) {
LayerInfos.getInstance(this.map, this.map.itemInfo)
.then(lang.hitch(this, function(operLayerInfos) {
operLayerInfos.traversal(function(layerInfo) {
if (layerInfo.title == layerTitle){
layerID = layerInfo.id;
}
});
}));
} else {
var itemInfo = this._obtainMapLayers();
LayerInfos.getInstance(this.map, itemInfo)
.then(lang.hitch(this, function(operLayerInfos) {
operLayerInfos.traversal(function(layerInfo) {
if (layerInfo.title == layerTitle){
layerID = layerInfo.id;
}
});
}));
}
return layerID;
},
_obtainMapLayers: function() {
// summary:
// obtain basemap layers and operational layers if the map is not webmap.
var basemapLayers = [],
operLayers = [];
// emulate a webmapItemInfo.
var retObj = {
itemData: {
baseMap: {
baseMapLayers: []
},
operationalLayers: []
}
};
array.forEach(this.map.graphicsLayerIds, function(layerId) {
var layer = this.map.getLayer(layerId);
if (layer.isOperationalLayer) {
operLayers.push({
layerObject: layer,
title: layer.label || layer.title || layer.name || layer.id || " ",
id: layer.id || " "
});
}
}, this);
array.forEach(this.map.layerIds, function(layerId) {
var layer = this.map.getLayer(layerId);
if (layer.isOperationalLayer) {
operLayers.push({
layerObject: layer,
title: layer.label || layer.title || layer.name || layer.id || " ",
id: layer.id || " "
});
} else {
basemapLayers.push({
layerObject: layer,
id: layer.id || " "
});
}
}, this);
retObj.itemData.baseMap.baseMapLayers = basemapLayers;
retObj.itemData.operationalLayers = operLayers;
return retObj;
},
Are there any errors in the browser console?
No errors or other message in the console. On opening, my widget temporarily turns off the infoWindow on the parcel layer and changes the cursor to a crosshair. When I click nothing happens, whereas before it would add the clicked-on parcel to map.graphics as expected.
That is just completely strange that you are not given some error when you click on the map? Do you have an error handler as well as a result handler for your deferred task like queryTask or FeatureLayer.selectFeatures?
Robert, Just to follow up after more testing: Here's the code I'm currently using:
_getLayerID: function _getLayerID(map, layerTitle) {
//local function to fetch the LayerID of layer in the map
var layerID;
LayerInfos.getInstance(map, map.itemInfo).then(lang.hitch(function (operLayerInfos) {
operLayerInfos.traversal(function(layerInfo) {
if (layerInfo.title == layerTitle){
layerID = layerInfo.id;
}
});
}));
return layerID;
},
startup: function startup() {
var _this = this; // used to fix the scope of objects inside events
var map = this.map;
var parcelLayerName = this.config.ParcelLayer_Name; //Name of parcel layer in the map, set from config.json
var parcelLayer = map.getLayer(this._getLayerID(map, parcelLayerName));
// Define the Selected Parcels Symbol
var highlightSymbol = this._getHighlightSymbol();
////////////// Listener Events
// Define OnClick event for clicking on a Parcel
this.onParcelClick = on.pausable(parcelLayer, 'click', lang.hitch(function (e) {
var taxlotString = esriLang.substitute(e.graphic.attributes, "${TAXLOT}");
var ownerString = esriLang.substitute(e.graphic.attributes, "${OWNERNAME}");
if (ownerString.length > 24) ownerString = ownerString.substring(0, 24) + "...";
var attr = { "Taxlot": taxlotString };
var highlightGraphic = new Graphic(e.graphic.geometry, highlightSymbol, attr);
map.graphics.add(highlightGraphic);
...
};
...
The rest end point for the map service layer I'm working with is https://....arcgis/rest/services/Public/PlanningBaseData/MapServer/2
The layerID returned from my _getLayerID function is "PlanningBaseData_5029_2".
The error I'm getting now is:
TypeError: Cannot read property 'on' of undefined
Adam,
That now makes sense. Your code is flawed when it come to layers coming from a map service vs. hosted one.
Here is what should work:
_getLayerID: function _getLayerID(map, layerTitle) {
//local function to fetch the LayerID of layer in the map
var layerID;
if (this.map.itemId) {
LayerInfos.getInstance(this.map, this.map.itemInfo)
.then(lang.hitch(this, function(operLayerInfos) {
operLayerInfos.traversal(function(layerInfo) {
if (layerInfo.title == layerTitle){
layerID = layerInfo.id;
}
});
}));
} else {
var itemInfo = this._obtainMapLayers();
LayerInfos.getInstance(this.map, itemInfo)
.then(lang.hitch(this, function(operLayerInfos) {
operLayerInfos.traversal(function(layerInfo) {
if (layerInfo.title == layerTitle){
layerID = layerInfo.id;
}
});
}));
}
return layerID;
},
_obtainMapLayers: function() {
// summary:
// obtain basemap layers and operational layers if the map is not webmap.
var basemapLayers = [],
operLayers = [];
// emulate a webmapItemInfo.
var retObj = {
itemData: {
baseMap: {
baseMapLayers: []
},
operationalLayers: []
}
};
array.forEach(this.map.graphicsLayerIds, function(layerId) {
var layer = this.map.getLayer(layerId);
if (layer.isOperationalLayer) {
operLayers.push({
layerObject: layer,
title: layer.label || layer.title || layer.name || layer.id || " ",
id: layer.id || " "
});
}
}, this);
array.forEach(this.map.layerIds, function(layerId) {
var layer = this.map.getLayer(layerId);
if (layer.isOperationalLayer) {
operLayers.push({
layerObject: layer,
title: layer.label || layer.title || layer.name || layer.id || " ",
id: layer.id || " "
});
} else {
basemapLayers.push({
layerObject: layer,
id: layer.id || " "
});
}
}, this);
retObj.itemData.baseMap.baseMapLayers = basemapLayers;
retObj.itemData.operationalLayers = operLayers;
return retObj;
},
Awesome. Thank you Robert!