Overview

You will learn: how to build an app to use client-side and server-side SQL and spatial expressions to limit data displayed.

Applications can perform server-side or client-side SQL and spatial filters to access and display data from feature layers. The source data for a feature layer can be hosted onArcGIS OnlineorArcGIS Enterpriseor it can be created from an array on the client.

  • Server-side Filters: To access a subset of the data from the server without adding the feature layer to a map, you can set the definitionExpression (SQL expression) on a FeatureLayer object.

  • Client-side Filters: To access a subset of data on the client, you have to add the feature layer to a map first, and then set the filter property on a FeatureLayerView object. The filter can be both a SQL and a spatial expression. Client-side filters execute very quickly.

One of the key differences between server-side and client-side filtering is that client-side filtering is only possible after the feature layer is added to a map and the attributes are present. To learn how to access and display data using a query, visit the Query a feature layer tutorial.

In this tutorial, you will apply server-side and client-side SQL filters to the Trails feature layer.

Click the options below to apply filters.

Steps

Create a starter app

  1. Open the JavaScript Starter App on CodePen.

  2. In CodePen, click Fork and save the pen as ArcGIS JavaScript Tutorials: Filter a feature layer.

Add a feature layer

Create a feature layer for the trails and add it to the map.

  1. In the require statement, add a reference to the FeatureLayer module.

        require([
          "esri/Map",
          "esri/views/MapView",
          "esri/layers/FeatureLayer"
        ],function(Map, MapView, FeatureLayer
    
  2. At the end of the code in the main function, create a FeatureLayer and set the url to access the Trails (Styled) feature layer, the outputFields to return all fields and values, and the popupTemplate to show the trail name and the elevation gain value in the popup content. Add the layer to the map.

           var featureLayer = new FeatureLayer({
             url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/Trails_Styled/FeatureServer/0",
             outFields: ["*"], // Return all fields so it can be queried client-side
             popupTemplate: {  // Enable a popup
               title: "{TRL_NAME}", // Show attribute value
               content: "The trail elevation gain is {ELEV_GAIN} ft."  // Display in pop-up
             }
           });
    
           map.add(featureLayer);
    

Create SQL expressions

  1. Define a list of SQL expressions and use the list to generate a Select HTML element with an option for each expression. Add the element to the top-right of the view.

          var sqlExpressions = ["TRL_ID = 0", "TRL_ID > 0",  "USE_BIKE = 'Yes'", "USE_BIKE = 'No'", "ELEV_GAIN < 1000", "ELEV_GAIN > 1000", "TRL_NAME = 'California Coastal Trail'"];
    
          var selectFilter = document.createElement("select");
          selectFilter.setAttribute("class", "esri-widget esri-select");
          selectFilter.setAttribute("style", "width: 275px; font-family: Avenir Next W00; font-size: 1em;");
    
          sqlExpressions.forEach(function(sql){
            var option = document.createElement("option");
            option.value = sql;
            option.innerHTML = sql;
            selectFilter.appendChild(option);
          });
    
          view.ui.add(selectFilter, "top-right");
    
  2. Run the code and test out the select element and the different query options.

    NOTE: No filter has been applied so all of the data will be displayed.

Apply a server-side filter

You can apply a server-side filter to limit the features returned from a feature layer by setting the definitionExpression.

  1. Create a function that sets the definitionExpression for a feature layer.

          function setFeatureLayerFilter(expression) {
            featureLayer.definitionExpression = expression;
          }
    
  2. Add an event handler to the selectFilter element to get the selected sql expression and call the setFeatureLayerFilter function.

          selectFilter.addEventListener('change', function (event) {
            setFeatureLayerFilter(event.target.value);
          });
    
  3. Run the code and select the different query options to filter the features in the layer.

Apply a client-side filter

You can apply a client-side filter by filtering the FeatureLayerView after the features have been loaded and the FeatureLayerView is ready. This type of filtering allows you to apply both SQL expressions and spatial relationship operators, and is often faster than a server-side filter.

  1. Create a function that gets a FeatureLayerView and applies a filter with the SQL expression when the layer is ready.

          function setFeatureLayerViewFilter(expression) {
            view.whenLayerView(featureLayer).then(function(featureLayerView) {
              featureLayerView.filter = {
                where: expression
              };
            });
          }
    
  2. Comment out the setFeatureLayerFilter function and call the setFeatureLayerViewFilter function passing it in the selected sql expression.

          selectFilter.addEventListener('change', function (event) {
            // setFeatureLayerFilter(event.target.value);
            setFeatureLayerViewFilter(event.target.value);
          });
    
  3. Run the code and select the different query options to filter the layer features. Click on features to show the pop-up information.

Congratulations, you're done!

Your app should look something like this.

Challenge

Style the excluded features

When a feature layer is filtered, only the features that match the criteria will be displayed. If you want to show the "excluded" features for reference, you can set the effect property on the FeatureLayerView. This property requires a filter and an excludedEffect, which will be used to style and draw the excluded features.

Update the filter with the code below to show the excluded features with 50% opacity.

      function setFeatureLayerViewFilter(expression) {
        view.whenLayerView(featureLayer).then(function(featureLayerView) {
          //*** UPDATE ***//
          // featureLayerView.filter = {
          //   where: expression
          // };
          featureLayerView.effect = {
            filter: {
              where: expression
            },
            excludedEffect: "opacity(50%)"
          }
        });
      }

Find and highlight features

Another form of filtering is to use the hitTest method on the view to find features at a given screen location. After the view and FeatureLayerView are ready, use hitTest to find and highlight features the cursor is over. hitTest returns features for all visible layers, so it is necessary to filter the results for the layer of interest.

NOTE: Highlighting features does not add new graphics to the map, it simply highlights the feature as part of the FeatureLayerView. The highlightOptions property can be used to change the color used to highlight the feature.

Add the following code to highlight features as the cursor moves.

      var highlight;

      view.whenLayerView(featureLayer).then(function(featureLayerView) {
        view.on("pointer-move", function(event){
          view.hitTest(event).then(function(response){
            // Only return features for the feature layer
            var feature = response.results.filter(function (result) {
             return result.graphic.layer === featureLayer;
            })[0].graphic;
            if (highlight) {
             highlight.remove();
            }
            // Highlight feature
            highlight = featureLayerView.highlight(feature);
          });
        });
      });
Content