1

Using ArcGIS API for Javascript 4, I want to create a drop-down list in the view that is dynamically populated based on the values available in a layer. When users select a value from this drop down and click a button, I want to query those features matching the value in the drop menu and have them appear on the map.

I've combined some elements from the following two tutorials for this:

https://developers.arcgis.com/javascript/latest/sample-code/tasks-query/index.html https://developers.arcgis.com/javascript/latest/sample-code/featurelayer-query/index.html

I can get the attributes to populate in the drop down list. However, clicking the button to query returns the following error message: "Promise rejected: Cannot perform query. Invalid query parameters."

I'm hoping this is just something simple I've overlooked, but I can't seem to find the issue. I am copying and pasting the complete code in case that's easiest to drop into CodePen or elsewhere to work with.

<html>
 <head>
 <meta charset="utf-8" />
 <meta
 name="viewport"
 content="initial-scale=1,maximum-scale=1,user-scalable=no"/>
 <title>Project viewer</title>
 <style>
 
 html,
 body,
 #mainViewDiv {
 padding: 0;
 margin: 0;
 height: 100%;
 width: 100%;
 }
 
 #optionsDiv {
 background-color: dimgray;
 color: white;
 padding: 10px;
 width: 90%;
 }
 
 #drop-downs {
 padding-bottom: 15px;
 }
 
 widget {
 /* Fill in later to style drop down widget */
 }
 
 </style>
 <link
 rel="stylesheet"
 href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
 />
 <script src="https://js.arcgis.com/4.15/"></script>
 <script>
 require([
 "esri/Map",
 "esri/views/MapView",
 "esri/Basemap",
 "esri/widgets/LayerList",
 "esri/layers/FeatureLayer",
 "esri/PopupTemplate",
 "esri/layers/GraphicsLayer",
 "esri/tasks/QueryTask",
 "esri/tasks/support/Query"
 ], function(
 Map,
 MapView,
 Basemap,
 LayerList,
 FeatureLayer,
 PopupTemplate,
 GraphicsLayer,
 QueryTask,
 Query
 ){
 
 var basinUrl = "https://services.arcgis.com/v01gqwM5QqNysAAi/arcgis/rest/services/Chesapeake_Bay_major_watersheds_feature/FeatureServer/0";
 
 //* for drop down
 var basinTypeSelect = document.getElementById("MajBas");
 
 //* Define the popup content for each result
 var popupTemplate = {
 title: "{MajBas}",
 fieldInfos: [
 {
 fieldName: "MajBas",
 label: "Major basin"
 }
 ]
 }; 
 
 // Layer - project footprints
 const basinLayer = new FeatureLayer({
 url: basinUrl,
 outFields: ["*"],
 visible: false
 });
 
 // Layer - dark nav basemap 
 const basemap = Basemap.fromId("streets-night-vector");
 
 //** Point querytask to project boundary URL
 var qTask = new QueryTask({
 url: basinUrl
 });
 
 //** Set the query parameters to always return geometry and all fields.
 //** Returning geometry allows us to display results on the map/view
 var params = new Query({
 returnGeometry: true,
 outFields: ["*"]
 });
 
 //* GraphicsLayer for displaying results
 var resultsLayer = new GraphicsLayer();
 
 var map = new Map({
 basemap : basemap,
 layers: [basinLayer]
 });
 var mainView = new MapView({
 container: "mainViewDiv",
 map: map,
 popup: {
 highlightEnabled: false,
 dockEnabled: true,
 dockOptions: {
 breakpoint: false,
 position: "top-right"
 }
 },
 center: [-75.325395, 40.306275],
 zoom: 5
 });
 
 // add widget with drop-down options
 mainView.ui.add("optionsDiv", {
 position: "bottom-left"
 });
 
 //* query all features from the basin layer
 mainView
 .when(function () {
 return basinLayer.when(function () {
 var query = basinLayer.createQuery();
 return basinLayer.queryFeatures(query);
 document.getElementById("doBtn").addEventListener("click", doQuery); 
 });
 })
 .then(getValues)
 .then(getUniqueValues)
 .then(addToSelect)
 .then(doQuery)
 
 //* return an array of all the values in the
 //* basin name field
 function getValues(response) {
 var features = response.features;
 var values = features.map(function (feature) {
 return feature.attributes.MajBas;
 });
 return values;
 }
 
 //* return an array of unique values in
 //* the MajBas field of the basin layer
 function getUniqueValues(values) {
 var uniqueValues = [];
 values.forEach(function (item, i) {
 if (
 (uniqueValues.length < 1 || uniqueValues.indexOf(item) === -1) &&
 item !== ""
 ) {
 uniqueValues.push(item);
 }
 });
 return uniqueValues;
 }
 
 //* Add the unique values to the basin type
 //* select element. This will allow the user
 //* to filter basin by name.
 function addToSelect(values) {
 values.sort();
 values.forEach(function (value) {
 var option = document.createElement("option");
 option.text = value;
 basinTypeSelect.add(option);
 });
 
 }
 
 //** Call doQuery() each time the button is clicked
 mainView.when(function () {
 mainView.ui.add("optionsDiv", "bottom-left");
 document.getElementById("doBtn").addEventListener("click", doQuery);
 });
 //**
 var attributeName = document.getElementById("MajBas");
 // Executes each time the button is clicked
 function doQuery() {
 // Clear the results from a previous query
 resultsLayer.removeAll();
 // Build new query
 params.where =
 "MajBas =" + attributeName.value;
 // executes query and calls getResults() once promise is resolved
 // promiseRejected() is called if the promise is rejected
 qTask.execute(params).then(getResults).catch(promiseRejected);
 }
 // Called each time the promise is resolved
 function getResults(response) {
 // Loop through each results and assign a symbol and PopupTemplate
 var basinResults = response.features.map(function (feature) {
 // Sets the symbol of each resulting feature
 feature.symbol = {
 type: "simple-fill", 
 color: [212, 161, 87, 0.25]
 };
 feature.popupTemplate = popupTemplate;
 return feature;
 });
 resultsLayer.addMany(basinResults);
 // print the number of results returned to the user
 document.getElementById("printResults").innerHTML =
 basinResults.length + " results found!";
 }
 // Called each time the promise is rejected
 function promiseRejected(error) {
 console.error("Promise rejected: ", error.message);
 } 
 
 
 
 });
 
 </script>
 </head>
 <body>
 <div id="mainViewDiv"></div>
 
 <div id="optionsDiv">
 <h2>Example</h2>
 <div id="drop-downs">
 <b>Basin</b>
 <br/>
 <select id="MajBas" class="widget"></select>
 </div>
 <br/>
 <br/>
 <button id="doBtn">Search</button> <br />
 <p><span id="printResults"></span></p>
 </div>
 
 </body>
</html>

"MajBasin" is the name of the field in the attribute table containing the basin names that are visible in the drop down.

PolyGeo
65.5k29 gold badges115 silver badges350 bronze badges
asked Oct 20, 2020 at 16:48

2 Answers 2

1

When setting params.where, the field name before the attribute value was missing. Thus, the updated code that builds a working query is:

params.where =
 "MajBas =" + "'" + basinTypeSelect.value + "'";
answered Oct 21, 2020 at 11:53
0

I populated the dropdowns by reading a json file.

Kadir Şahbaz
78.6k57 gold badges260 silver badges407 bronze badges
answered Aug 9, 2021 at 19:41

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.