Hello Community,
I am just learning ArcGIS Maps SDK for Javascript, and in the process, I am trying to create a simple application that should highlight the features after executing a query. The code is as follows :
require(["esri/config", "esri/Map", "esri/views/MapView", "esri/layers/FeatureLayer", "esri/widgets/Popup", "esri/widgets/Legend", "esri/widgets/LayerList", "esri/rest/query", "esri/rest/support/Query"], function (esriConfig, Map, MapView, FeatureLayer, Popup, Legend, LayerList, query, Query) {
esriConfig.apiKey = "XXXXXXXXX";
const colors = ["#d92b30", "#3cccb4", "#ffdf3c", "#c27c30", "#f260a1"];
const commonProperties = {
type: "simple-marker",
width: "2px",
style: "circle"
};
const gujarat = {
...commonProperties,
color: colors[0]
}
const odisha = {
...commonProperties,
color: colors[1]
}
const punjab = {
...commonProperties,
color: colors[2]
}
const tamilnadu = {
...commonProperties,
color: colors[3]
}
const other = {
...commonProperties,
color: colors[4]
}
const ptrenderer = {
type: "unique-value",
legendOptions:{
title: "State Name"
},
defaultSymbol: other,
defaultLabel: "Others",
field: "state",
uniqueValueInfos: [
{
value: "Gujarat", // code for Gujarat
symbol: gujarat,
label: "Gujarat"
},
{
value: "Odisha", // code for Odisha
symbol: odisha,
label: "Odisha"
},
{
value: "Punjab", // code for Punjab
symbol: punjab,
label: "Punjab"
},
{
value: "Tamil Nadu", // code for Tamil Nadu
symbol: tamilnadu,
label: "Tamil Nadu"
}
]
}
const params = new Query({
returnGeometry: true,
outFields: ["*"]
});
const map = new Map({
basemap: "arcgis-topographic"
});
const view = new MapView({
map: map,
center: [78.9629, 20.5937],
zoom: 5,
container: "viewDiv",
popup: new Popup({
defaultPopupTemplateEnabled : true
}),
});
const featureLayer = new FeatureLayer({
url : "https://services6.arcgis.com/Cj6ppUYzylKGUnEi/arcgis/rest/services/India_Wetlands/FeatureServer",
renderer: ptrenderer
});
view.when(() => {
view.ui.add("optionsDiv", "bottom-right");
document.getElementById("doBtn").addEventListener("click", doQuery);
});
const attributeName = document.getElementById("attSelect");
const expressionSign = document.getElementById("signSelect");
const value = document.getElementById("valSelect");
function doQuery() {
// Clear the results from a previous query and close the popup if its open.
//featureLayer.removeAll();
if (view.popup.visible) {
view.closePopup();
}
params.where = attributeName.value + expressionSign.value + "'" + value.value + "'";
// executes the query and calls getResults() once the promise is resolved
// promiseRejected() is called if the promise is rejected
featureLayer.queryFeatures(params).then(getResults).catch(promiseRejected);
}
function getResults(results){
const symbol = {
type: "simple-marker",
color : [20, 30, 100, 0.5],
outline: {
color: "white",
width: .5
}
}
results.features.map((feature) => {
feature.symbol = symbol
return feature
})
}
// Called each time the promise is rejected
function promiseRejected(error) {
console.error("Promise rejected: ", error.message);
}
view.when(()=>{
const layerlist = new LayerList({
view : view
})
view.ui.add(layerlist, "top-right")
})
view.ui.add(new Legend({ view }), "bottom-left");
//const featureLayer = new FeatureLayer({
//url : "https://services6.arcgis.com/Cj6ppUYzylKGUnEi/arcgis/rest/services/India_Wetlands/FeatureServer",
//renderer: ptrenderer
//});
const statesLayer = new FeatureLayer({
url: "https://livingatlas.esri.in/server1/rest/services/IAB/State/MapServer/0"
})
//});
map.add(statesLayer,0)
map.add(featureLayer)
});
The application loads just fine and am able to see the features however, after executing the query nothing happens and there is no error in the console as well.
I have used the following links as reference :
https://developers.arcgis.com/javascript/latest/tutorials/query-a-feature-layer-sql/
https://developers.arcgis.com/javascript/latest/sample-code/query/
I believe as both the links are referring to graphic layer and am using a feature layer, that could be causing some issue. Not sure what am I missing here.
Any suggestions would be helpful.
Solved! Go to Solution.
So you need to highlight features using FeatureLayerView.highlight method.
Please take a look this codepen: https://codepen.io/U_B_U/pen/PoLVeVq?editors=1000
This sample could be useful: https://developers.arcgis.com/javascript/latest/sample-code/highlight-features-by-geometry/
Can you share your query parameters? I am guessing that is where the issue is. The code above does not help to narrow down the issue. You can open the network request tab and see if the service is returning any results for your query since you are issuing the query on the layer.
@UndralBatsukh Here is the rest of HTML code that constructs the query:
<div id="viewDiv"></div>
<div class="esri-widget" id="optionsDiv">
<h2>Test.</h2>
<select class="esri-widget" id="attSelect">
<option value="State">State</option>
</select>
<select class="esri-widget" id="signSelect">
<option value="=">is equal to</option>
</select>
<select class="esri-widget" id="valSelect">
<option value="Gujarat">Gujarat</option>
<option value="Tamil Nadu"> Tamil Nadu</option>
<option value="Punjab">Punjab</option>
<option value="Odisha">Odisha</option>
</select>
<br />
<br />
<button class="esri-widget" id="doBtn">Do Query</button> <br />
<p><span id="printResults"></span></p>
</div>
I also checked the network tab and I can see that query does get executed, the issue is that features which satisfy a particular query are not getting highlighted.
The problem here is that you're trying to highlight graphics in a FeatureLayer by assigning a new symbol to them. That would've worked in 3.x, but not in 4.x. To highlight FeatureLayer graphics in 4.x, you need to get a reference to the layer's associated FeatureLayerView, and then use its highlight method.
So you need to highlight features using FeatureLayerView.highlight method.
Please take a look this codepen: https://codepen.io/U_B_U/pen/PoLVeVq?editors=1000
This sample could be useful: https://developers.arcgis.com/javascript/latest/sample-code/highlight-features-by-geometry/
Thank You @UndralBatsukh . This is exactly that I was hoping to achieve.