Skip to content

Query features from a FeatureLayerView

This sample demonstrates how query features that are visible with the current extent of the view. Census tract names of the features visible within the view's extent are displayed in the calcite-list-item component. When user clicks a tract name in the list, the map zooms to the corresponding tract feature and opens its popup.

The sample uses a FeatureLayer created from a portalItem pointing to a feature service containing 5-year estimates of current marital status by census tract.

It leverages the FeatureLayerView.queryFeatures() method to query features already available for drawing on the client-side, avoiding additional network requests. A FeatureLayerView is created when a FeatureLayer is added to a Map or a Scene, and provides methods and properties to query, filter, and highlight features currently visible in the view.

How it works

The FeatureLayer is created from a portalItem with a configured popupTemplate. The layer's outFields property is set to include all fields used by popupTemplate and client-side queries. This ensures the required attributes are available on the feature layer view, improving performance and preventing extra server requests.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// create the FeatureLayer pointing to the census tracts layer
const featureLayer = new FeatureLayer({
  portalItem: {
    id: "6885d0bc6bdc402683eff443e7081ef6"
  },
  // needed for query and popup
  // having fields on the client side improves performance
  // for example popup can display field values without making a request to the server
  outFields: [
    "County", "NAME", "GEOID", "B12001_calc_pctDivorcedE",
    "B12001_calc_pctMarriedE", "B12001_calc_pctNeverE",
    "B12001_calc_numDivorcedE", "B12001_calc_numMarriedE", "B12001_calc_numNeverE"
  ],
});

After adding the layer to the map, its FeatureLayerView can be accessed via the view’s whenLayerView() method.

Use dark colors for code blocksCopy
1
2
3
// wait for the layer view to be created
const layerView = await viewElement.whenLayerView(featureLayer);
// do something with the layerView

The sample queries features whenever the map is panned or navigated to a new extent to update the list. However, before running the query, the sample waits until the FeatureLayerView has finished fetching data for that extent by checking that its dataUpdating property is false. This ensures that the query is executed against the most current set of features available in the view, avoiding incomplete or outdated results.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// watch for the layer view to finish fetching its data
// layer view will fetch data as the user navigates the map
reactiveUtils.when(
  () => !layerView.dataUpdating,
  async () => {

    // query all the features within the view's extent.
    try {
      const featureSet = await layerView.queryFeatures({
        geometry: viewElement.extent,
        returnGeometry: true,
        orderByFields: ["GEOID"],
      });

      // store the queried features for later use
      graphics = featureSet.features;

      // populate the list with the queried features
      // use createDocumentFragment for better performance
      const fragment = document.createDocumentFragment();
      // loop through the features and create a list item for each
      // displaying the census tract name
      // users can click on a list item to zoom to the feature and open a popup
      graphics.forEach((result, index) => {
        const attributes = result.attributes;
        const name = attributes.NAME;
        const item = document.createElement("calcite-list-item");
        item.setAttribute("label", name);
        item.setAttribute("value", index);
        item.addEventListener("calciteListItemSelect", onListClickHandler);
        fragment.appendChild(item);
      });

      // Empty the current list
      resultsList.innerHTML = "";
      resultsList.appendChild(fragment);
    } catch (error) {
      console.error("query failed: ", error);
    }
  },
);

When a list item is selected, the map zooms to the feature and opens its popup at the feature’s centroid, calculated using centroidOperator.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
// zoom to the feature's extent and open a popup
await viewElement.goTo(result.geometry.extent.expand(2));
const centroid = centroidOperator.execute(result.geometry);

viewElement.openPopup({
  features: [result],
  location: centroid,
});

Additional resources

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.