layerView.queryExtent returns null if features are not in current map extent

1575
5
09-02-2021 07:46 AM
Strahanjen
Frequent Contributor

I'm using the follow snippet of code to zoom to the extent of graphics in a featurelayer. It works great when the map starts at the full extent. If I remove some graphics and add new graphics that are in an area that is not currently visible on the map, the queryExtent returns a null extent. However, if I add code to zoom to the full extent of the map first, then the queryExtent returns the extent. Anyone know how I can get this to work without zooming home each time I want to zoom to the extent of the layer? 

    function zoomToLayer(layer) {

        /*first zoom to home to get around queryExtent bug. 
         Getting the queryExtent for a  layerview does not work if the 
         extent of the features is not visible in the map */
        /*
        view.goTo({
            center: [-94.25,45.98],
            zoom: 7
        });*/
          
        view.whenLayerView(layer).then((layerView=> {
            var handle = layerView.watch("updating"function(val) {
                // wait for the layer view to finish updating
                if (!val) {
                  layerView.queryExtent().then(function(response) {
                      console.log(response);
                    //remove the layer updating watch handler
                    handle.remove();
                    // go to the extent of all the graphics in the layer view
                    view.goTo(response.extent);
                  });
                }
              });
        });

    }
0 Kudos
5 Replies
ReneRubalcava
Honored Contributor

The LayerView only has features that are currently displayed in the browser. When you query the extent of them, it only has the information to calculate the extent of displayed features. If you need the true extent of the data source, you can use the layer.queryExtentI() method or if defined, layer.fullExtent property of the layer.

0 Kudos
Strahanjen
Frequent Contributor

Glad to have that explanation. I'm not sure I can switch to using layer.queryExtent because I'm working with a client side FeatureLayer. According to the documentation: 

"Note that when working with client-side FeatureLayers, you will need to call queryExtent() on the FeatureLayerView to see the expected behavior."

Any other suggestions? 

Thanks,

Jennifer

0 Kudos
ReneRubalcava
Honored Contributor

Are you using applyEdits to add features to the layer or adding them via source when creating it?  If that's the case, you can still use layer.queryExtent() and it will work. It's still client-side.

0 Kudos
UndralBatsukh
Esri Regular Contributor

Hi there, 

@ReneRubalcava is 100% correct. Please use the FeatureLayer.queryExtent() to zoom to the full extent of all features stored in your client-side feature collection especially if the features are being added or removed.

I will update the sample description accordingly since it is outdated.

-Undral 

0 Kudos
Jeff-Reinhart
Regular Contributor

Would like to clarify on this topic a little further. If I am interpreting the original post right, the intended approach is:

  • Load all features for a FeatureLayer to the map.
  • Add a definitionExpression to the FeatureLayer to filter the layer.
  • Set the map extent to the extent of the filtered FeatureLayer.
  • Change the definitionExpression on the FeatureLayer to filter to another feature or feature set in an area not currently in the view.
  • Set the map extent to that of the updated filtered FeatureLayer.

The goal is to do this without having to query the service to get the extent of the filtered FeatureLayer. Considering the FeatureLayer is already loaded to the client, another query to the service should not be necessary. I have been experimenting with the same approach.

The docs for FeatureLayer.queryExtent() state “To query for the extent of features/graphics available to or visible in the View on the client rather than making a server-side query, you must use the FeatureLayerView.queryExtent() method.”

This would indicate that the approach above is not possible without zooming back out to the full FeatureLayer extent prior to setting the map extent the second time. Running FeatureLayer.queryExtent() will result in another query to the service. Running FeatureLayerView.queryExtent() will not query the service but it will not correctly set the map extent unless the next feature set is in the view when FeatureLayerView.queryExtent() is executed.

I did some testing, and what I am seeing indicates that running FeatureLayer.queryExtent() DOES query the service. Running FeatureLayerView.queryExtent() does not query the service.

Am I missing something?

0 Kudos