AnsweredAssumed Answered

Query visible graphics client-side using Webmap

Question asked by raul.jimenezesri-es-esridist Employee on Apr 1, 2018
Latest reply on Apr 4, 2018 by raul.jimenezesri-es-esridist

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>
        <!-- TODO: Display visible graphics-->
    </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 // return "Startups"
l.featuresView.numFeatures // return 374
l.featuresView.graphics // return undefined

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.

Outcomes