I'm using JS API 4.6 and I'm trying to show in a table all graphics been displayed in the current extent directly querying the client/view.
You can find a live sample of the skeleton I'm using here or directly in here:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
<title>Query graphics on webmap</title>
<link rel="stylesheet" href="https://js.arcgis.com/4.6/esri/css/main.css">
<script>
var dojoConfig = {
has: {
"esri-featurelayer-webgl": 1
}
};
</script>
<script src="https://js.arcgis.com/4.6/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 400px;
width: 100%;
}
</style>
<script>
require([
"esri/WebMap",
"esri/views/MapView",
"esri/widgets/LayerList",
"esri/widgets/Legend",
"esri/geometry/geometryEngine",
"esri/core/watchUtils",
"esri/tasks/support/Query",
"dojo/domReady!"
],
function(
WebMap,
MapView,
LayerList,
Legend,
geometryEngine,
watchUtils,
Query
) {
webmap = new WebMap({
portalItem: {
id: "19d21df5e87f4f5a9aa5b8d678b174d6"
}
});
view = new MapView({
container: "viewDiv",
map: webmap,
popup: {
dockEnabled: true,
dockOptions: {
buttonEnabled: false,
breakpoint: {
width: 1000
},
position: "bottom-left"
}
},
});
view.when(function() {
var featureLayer = webmap.layers.getItemAt(0);
featureLayer.labelingInfo = [{
labelExpression: "[title]",
labelExpressionInfo: {
"expression": "$feature[\"title\"]"
},
labelPlacement: "always-horizontal",
symbol: {
type: "text",
color: [ 255,255,255,0.85 ],
font: {
size: 16,
weight: "bold",
family: "Arial Unicode MS"
},
haloColor: [255, 255, 255, 255],
haloSize: 0.75,
}
}];
var legend = new Legend({
view: view,
layerInfos: [{
layer: featureLayer,
title: "Actor type"
}]
});
view.ui.add(legend, "bottom-right");
});
view.when(function() {
var layerList = new LayerList({
view: view
});
view.ui.add(layerList, "top-right");
});
watchUtils.whenTrue(view, "stationary", function() {
if (view.extent) {
var info = `the view extent changed: \n
xmin = ${view.extent.xmin.toFixed(2)} xmax = ${view.extent.xmax.toFixed(2)} \n
ymin = ${view.extent.ymin.toFixed(2)} ymax = ${view.extent.ymax.toFixed(2)}`;
console.log(info);
}
});
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div>
<p>Visible graphics:</p>
</div>
</body>
</html>
I have been trying different things:
1) Using queryGraphics as I found at the GraphicsLayerView | API Reference | ArcGIS API for JavaScript 4.6
l = view.allLayerViews.getItemAt(1);
l.queryGraphics().then(function(results){
console.log("results=",results);
});
But the "then" promise was not resolved, maybe because I didn't added in the right place.
2) So I tried using queryFeatures, similar al Robert Scheitlin, GISP suggested in Capture attribute values from a WebMap without click event directly on the console:
view.allLayerViews.getItemAt(1).queryFeatures(query).always(function(results){
console.info(results);
});
But this time I used "always" and I got an:
{
name: "FeatureLayerView2D",
message: "Not ready to execute query",
details: undefined
}
3) I didn't know what "Not ready to execute query" means so I keep trying this time using the view event layerview-create as Ken Buja mentioned atCannot access items array property of MapView.allLayerViews (ArcJS API 4.4) :
view.on("layerview-create", function(event) {
var query = new Query();
query.where = '1=1';
query.outSpatialReference = view.spatialReference;
query.outFields = ["*"];
console.log("event.layer.title=",event.layer.title)
event.layerView.queryFeatures(query).always(function(results){
console.info(results);
});
});
But I got the same error.
4) Next time I tried a different way, using layerView.featuresView.graphics as Thomas Solow mentioned at Design Question - Feature Layer Queries on Client-Side?
l = view.allLayerViews.getItemAt(1);
l.layer.title
l.featuresView.numFeatures
l.featuresView.graphics
And I don't understand why graphics are undefined this time... ^_^. I also tried using queryFeatures on l.featuresView but the method didn't exist.
5) Desperately I also tried using the Accessor:
l = view.allLayerViews.getItemAt(1)
l.watch("updating", function (newValue, oldValue, propertyName, target) {
target.queryFeatures().then(function (results) {
console.log("results", results);
})
console.log("graphics=", target.featuresView.graphics")
});
But nothing ;(
I have spent several hours reading, trying different things and searching in the answered questions, but I'm running out of ideas. Please, could you help me solve this problem? I guess it should be quite easy to do but I'm not able to make it work.
Thanks in advance.