I am tryin to piece together a few example and simply trying to query a Rest Endpoint and display those records that are returned.
I am using the scrip below. I get the correct number of results returned but can get them to display.
Any thoughts to why?
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>
Basic Querying in FeatureLayer | Sample | ArcGIS API for JavaScript 4.24
</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.24/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.24/"></script>
<style>
html,
body,
#viewDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#optionsDiv {
background-color: white;
color: black;
padding: 6px;
max-width: 400px;
}
</style>
<script>
require([
"esri/Map","esri/Graphic","esri/views/MapView","esri/layers/FeatureLayer",
"esri/widgets/Legend","esri/rest/support/Query"
], (Map, Graphic, MapView, FeatureLayer, Legend, Query) => {
const map = new Map({
basemap: "gray-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
});
layer.load().then(() => {
queryFeatures1();
});
function queryFeatures1() {
var collectionIDvalue1 = '123';
var collectionIDvalue2 = '124';
var collectionIDstring = "CollectionID = " + "'" + collectionIDvalue1 + "'";
const layer = new FeatureLayer({
url: "https://servicesdev.dwr.virginia.gov/arcgis/rest/services/CWSS/AquaDB_Locations/FeatureServer/0"
});
const query = new Query();
query.where = collectionIDstring;
query.returnGeometry = true;
query.outFields = [ "CollectionID", "GlobalID" ];
layer.queryFeatureCount(query)
.then(function(numResults){
alert("There are " + numResults + " return from this query");
});
layer.queryFeatures(query)
.then((results) => {
var countFeatures = results.features.length;
alert("Feature count: " + countFeatures);
displayResults(results);
}).catch((error) => {
console.log(error.error);
});
}
function displayResults(results) {
// Create a blue polygon
const symbol = {
type: "simple-fill",
color: [ 20, 130, 200, 0.5 ],
outline: {
color: "white",
width: .5
},
};
const popupTemplate = {
title: "Locations {OBJECTID}",
content: "ObjectID: {OBJECTID} <br> Collection ID: {CollectionID}"
};
// Assign styles and popup to features
results.features.map((feature) => {
feature.symbol = symbol;
feature.popupTemplate = popupTemplate;
return feature;
});
// Clear display
view.popup.close();
view.graphics.removeAll();
// Add features to graphics layer
view.graphics.addMany(results.features);
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Solved! Go to Solution.
Your symbol is a simple-fill, that's for polygons, that's why you couldn't see them. Change it to simple-marker and they'll show up.
https://codepen.io/odoe/pen/jOzReRb?editors=1000
You can also accomplish this with a definitionExpression on the FeatureLayer, unless the query in your app is done dynamically, and you need the data for something other than display. You could always update the definitionExpression during runtime too.
I added a graphics layer and tried to add the results to that... Modifyed from original script above
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>
Basic Querying in FeatureLayer | Sample | ArcGIS API for JavaScript 4.24
</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.24/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.24/"></script>
<style>
html,
body,
#viewDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#optionsDiv {
background-color: white;
color: black;
padding: 6px;
max-width: 400px;
}
</style>
<script>
require([
"esri/Map","esri/Graphic","esri/views/MapView","esri/layers/FeatureLayer",
"esri/widgets/Legend","esri/rest/support/Query", "esri/layers/GraphicsLayer"
], (Map, Graphic, MapView, FeatureLayer, Legend, Query, GraphicsLayer) => {
var graphicA = new Graphic();
var layerGraphics = new GraphicsLayer({
graphics: [graphicA]
});
const layer = new FeatureLayer({
url: "https://servicesdev.dwr.virginia.gov/arcgis/rest/services/CWSS/AquaDB_Locations/FeatureServer/0",
outFields: ["*"]
});
const map = new Map({
basemap: "gray-vector", //,
layers: [layerGraphics]
});
const view = new MapView({
container: "viewDiv",
map: map,
});
layer.load().then(() => {
queryFeatures1();
});
function queryFeatures1() {
var collectionIDvalue1 = '123';
var collectionIDvalue2 = '124';
var collectionIDstring = "CollectionID = " + "'" + collectionIDvalue1 + "'";
const layer = new FeatureLayer({
url: "https://servicesdev.dwr.virginia.gov/arcgis/rest/services/CWSS/AquaDB_Locations/FeatureServer/0"
});
const query = new Query();
query.where = collectionIDstring;
query.returnGeometry = true;
query.outFields = [ "CollectionID", "GlobalID" ];
layer.queryFeatureCount(query)
.then(function(numResults){
alert("There are " + numResults + " return from this query");
});
layer.queryFeatures(query)
.then((results) => {
var countFeatures = results.features.length;
alert("Feature count: " + countFeatures);
displayResults(results);
}).catch((error) => {
console.log(error.error);
});
}
function displayResults(results) {
// Create a blue polygon
const symbol = {
type: "simple-fill",
color: [ 20, 130, 200, 0.5 ],
outline: {
color: "white",
width: .5
},
};
const popupTemplate = {
title: "Locations {OBJECTID}",
content: "ObjectID: {OBJECTID} <br> Collection ID: {CollectionID}"
};
// Assign styles and popup to features
results.features.map((feature) => {
feature.symbol = symbol;
feature.popupTemplate = popupTemplate;
return feature;
});
// Clear display
//view.popup.close();
//view.graphics.removeAll();
//// Add features to graphics layer
//view.graphics.addMany(results.features);
view.popup.close();
view.layerGraphics.removeAll();
// Add features to graphics layer
view.layerGraphics.addMany(results.features);
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
Again, you need to add any layer to the map for it to be seen. The addition below makes the layer show up, but there's nothing in the graphicslayer yet as you only created a new, empty graphic, even though the graphicslayer is there now.
const view = new MapView({
container: "viewDiv",
map: map,
});
map.addMany([layer, layerGraphics]);
layer.load().then(() => {
queryFeatures1();
});
You need to add the layer to the map. In the code below I pulled out your layer creation from the 'queryFeatures' function and put it just after the View creation, and then added it to the map. Your code works fine after that. I would recommend you put the querying of the layer under the View initilization (when) instead of how you are doing it but it does work this way.
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>
Basic Querying in FeatureLayer | Sample | ArcGIS API for JavaScript 4.24
</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.24/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.24/"></script>
<style>
html,
body,
#viewDiv {
height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
#optionsDiv {
background-color: white;
color: black;
padding: 6px;
max-width: 400px;
}
</style>
<script>
require([
"esri/Map","esri/Graphic","esri/views/MapView","esri/layers/FeatureLayer",
"esri/widgets/Legend","esri/rest/support/Query"
], (Map, Graphic, MapView, FeatureLayer, Legend, Query) => {
const map = new Map({
basemap: "gray-vector"
});
const view = new MapView({
container: "viewDiv",
map: map,
});
const layer = new FeatureLayer({
url: "https://servicesdev.dwr.virginia.gov/arcgis/rest/services/CWSS/AquaDB_Locations/FeatureServer/0"
});
map.add(layer);
layer.load().then(() => {
queryFeatures1();
});
function queryFeatures1() {
var collectionIDvalue1 = '123';
var collectionIDvalue2 = '124';
var collectionIDstring = "CollectionID = " + "'" + collectionIDvalue1 + "'";
const query = new Query();
query.where = collectionIDstring;
query.returnGeometry = true;
query.outFields = [ "CollectionID", "GlobalID" ];
layer.queryFeatureCount(query)
.then(function(numResults){
alert("There are " + numResults + " return from this query");
});
layer.queryFeatures(query)
.then((results) => {
var countFeatures = results.features.length;
alert("Feature count: " + countFeatures);
displayResults(results);
}).catch((error) => {
console.log(error.error);
});
}
function displayResults(results) {
// Create a blue polygon
const symbol = {
type: "simple-fill",
color: [ 20, 130, 200, 0.5 ],
outline: {
color: "white",
width: .5
},
};
const popupTemplate = {
title: "Locations {OBJECTID}",
content: "ObjectID: {OBJECTID} <br> Collection ID: {CollectionID}"
};
// Assign styles and popup to features
results.features.map((feature) => {
feature.symbol = symbol;
feature.popupTemplate = popupTemplate;
return feature;
});
// Clear display
view.popup.close();
view.graphics.removeAll();
// Add features to graphics layer
view.graphics.addMany(results.features);
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>
when I do this I get all the features displaying in the map not the 2 that where returned from the query.
I dont want to show all the features JUST the ones that are returned from the query.
I want to query the Main RestEndpoint and grab the two records and then push them to a graphics layer. So this way I don have to display ALL the values at ANY point.
Your symbol is a simple-fill, that's for polygons, that's why you couldn't see them. Change it to simple-marker and they'll show up.
https://codepen.io/odoe/pen/jOzReRb?editors=1000
You can also accomplish this with a definitionExpression on the FeatureLayer, unless the query in your app is done dynamically, and you need the data for something other than display. You could always update the definitionExpression during runtime too.
Fantastic... thanks so much ...
SO - Am I correct to assume that this approach does now load all the points until the query is done and then and only then does it display the two points that are being shown
Correct. If you are using the FeatureLayer strictly as a source to query, you don't need to add it to the map, and push results into a GraphicsLayer. Only what you query is requested. You could also use the definitionExpression of a FeatureLayer to achieve the same result, it just depends on your workflow.
@ReneRubalcava Yea thanks... I was looking at the definitionExpression but my workflow lead me in this direction... Cheers. And thanks for the input