Learn how to execute a SQL query to access polygon A polygon is a type of geometry containing an array of rings and a spatial reference. Each ring contains an array of point coordinates, where the first and last point are the same. Learn more features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more from a feature layer A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more .

Use the selector to choose a SQL where clause to query and display features.

A feature layer A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more can contain a large number of features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more stored in ArcGIS ArcGIS is the brand name for all of the desktop, server, and developer products and technologies offered by Esri. Learn more . To access a subset of the features, you can execute either a SQL or spatial query, or both at the same time. You can return feature attributes Attributes are fields and values for a single feature or non-spatial record. They are typically stored in a database or service such as a feature service. Learn more , geometry A geometry is a geometric shape, such as a point, polyline, or polygon, that contains one or more coordinates and a spatial reference. Learn more , or both attributes and geometry for each record. SQL and spatial queries are useful when you want to access only a subset of your hosted data.

In this tutorial, you will perform server-side SQL queries to return a subset of features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more in the LA County Parcel feature layer A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more . The feature layer contains over 2.4 million features. The resulting features are displayed as graphics A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more on the map.

Prerequisites

Steps

Create a new pen

  1. To get started, either complete the Display a map tutorial or .

Get an access token

You need an access token An access token is an authorization string that provides access to secure ArcGIS content, data, and services. Its capabilities are determined by the privileges it supports. It is obtained by implementing API key authentication, User authentication, or App authentication. Learn more with the correct privileges to access the location services ArcGIS Location Services, also referred to as Location Services, are services hosted by Esri that provide geospatial functionality for developing mapping applications. They include the ArcGIS Basemap Styles service, ArcGIS Static Basemap Tiles service, ArcGIS Places service, ArcGIS Geocoding service, ArcGIS Routing service, ArcGIS GeoEnrichment service, and ArcGIS Elevation service. An ArcGIS Location Platform or ArcGIS Online account is required to use the services. Learn more used in this tutorial.

  1. Go to the Create an API key tutorial and create an API key An API key is a long-lived access token created using API key credentials. They are valid for up to one year and are typically embedded directly into client applications. Learn more with the following privilege(s) Privileges are a set of permissions assigned to ArcGIS accounts, developer credentials, and applications that grant access to secure resources and functionality in ArcGIS. Learn more :
    • Privileges
      • Location services > Basemaps
    • Item access
      • Note: If you are using your own custom data layer for this tutorial, you need to grant the API key credentials API key credentials are an item that contains the parameters used to create and manage long-lived access tokens for API key authentication. They are a type of developer credential. Learn more access to the layer item. Learn more in Item access privileges.
  2. In CodePen, set the apiKey property on the global esriConfig variable to your access token.
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };

To learn about other ways to get an access token, go to Types of authentication.

Create a SQL selector

ArcGIS feature layers A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more support a standard SQL query where clause. Use a Calcite Select component to provide a list of SQL queries for the LA County Parcels feature layer A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more .

  1. Add a Calcite Select component to the top-right slot of the map. This component has child option components, each with a different SQL query.

    33 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    93 collapsed lines
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    queryFeatureLayer(viewElement.extent);
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    parcelLayer
    .queryFeatures(parcelQuery)
    .then((results) => {
    console.log("Feature count: " + results.features.length);
    displayResults(results);
    })
    .catch((error) => {
    console.log(error.error);
    });
    }
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    // Assign styles and popup to features
    results.features.map((feature) => {
    feature.symbol = symbol;
    feature.popupTemplate = popupTemplate;
    return feature;
    });
    // Clear display
    viewElement.closePopup();
    viewElement.graphics.removeAll();
    // Add features to graphics layer
    viewElement.graphics.addMany(results.features);
    }
    </script>
    </body>
    </html>
  2. Verify that the select component is created.

Add modules and event listeners

  1. Add a <script> tag in the <body> following the <arcgis-map> component. Use $arcgis.import() to add the FeatureLayer module.

    Use the document.querySelector() method to access the map, select, and the default option components. Create a whereClause variable to store the first option value.

    47 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    </script>
    5 collapsed lines
    </body>
    </html>
  2. Wait for the map to be ready with viewOnReady.

    47 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    </script>
    5 collapsed lines
    </body>
    </html>
  3. Create an event listener to listen for the select component changes and update the whereClause variable to the selected value.

    57 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    });
    6 collapsed lines
    </script>
    </body>
    </html>

Create a feature layer to query

Use the FeatureLayer class to access the LA County Parcel feature layer A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more . Since you are performing a server-side query, the feature layer does not need to be added to the map.

  1. Create a parcelLayer and set the url property to access the feature layer in the feature service.
    57 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    6 collapsed lines
    </script>
    </body>
    </html>

Execute a query

Use the queryFeatures method to perform a SQL query against the feature layer A feature layer (server-side) is a spatially-enabled table in a feature service. All features in a feature layer share the same geometry type and set of fields. Learn more . The Query will be autocast when the method is called.

  1. Create a queryFeatureLayer function with extent parameter. Define a parcelQuery element and set the where property to the whereClause. Set the spatialProperty to only return features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more that intersect the geometry, which is restricted to the visible extent of the map. The outFields property will return only a subset of the attributes Attributes are fields and values for a single feature or non-spatial record. They are typically stored in a database or service such as a feature service. Learn more . Lastly, set returnGeometry to true so that the features can be displayed.

    66 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    }
    8 collapsed lines
    </script>
    </body>
    </html>
  2. Call the queryFeatures method on the parcelLayer using parcelQuery. To view the number of features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more returned, write the result length to the console. This will be updated in the next step.

    71 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    parcelLayer
    .queryFeatures(parcelQuery)
    .then((results) => {
    console.log("Feature count: " + results.features.length);
    })
    .catch((error) => {
    console.log(error.error);
    });
    }
    40 collapsed lines
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    // Assign styles and popup to features
    results.features.map((feature) => {
    feature.symbol = symbol;
    feature.popupTemplate = popupTemplate;
    return feature;
    });
    // Clear display
    viewElement.closePopup();
    viewElement.graphics.removeAll();
    // Add features to graphics layer
    viewElement.graphics.addMany(results.features);
    }
    </script>
    </body>
    </html>
  3. Update the event handler to call the queryFeatureLayer function when the selector changes.

    59 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    queryFeatureLayer(viewElement.extent);
    });
    71 collapsed lines
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    parcelLayer
    .queryFeatures(parcelQuery)
    .then((results) => {
    console.log("Feature count: " + results.features.length);
    displayResults(results);
    })
    .catch((error) => {
    console.log(error.error);
    });
    }
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    // Assign styles and popup to features
    results.features.map((feature) => {
    feature.symbol = symbol;
    feature.popupTemplate = popupTemplate;
    return feature;
    });
    // Clear display
    viewElement.closePopup();
    viewElement.graphics.removeAll();
    // Add features to graphics layer
    viewElement.graphics.addMany(results.features);
    }
    </script>
    </body>
    </html>
  4. At the top-right, click Run. Choose a SQL query from the selector. At the bottom left, click Console to view the number of features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more returned from each query.

Display features

To display the features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more returned from the SQL query, add them to the view A view is a UI component that draws the layers in a map or scene and controls their extent (area) and geographic features. Learn more as polygon graphics A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more . Define a pop-up A pop-up is a visual element used to display data for features or graphics in a map. Learn more also so the attributes can be displayed when features are clicked.

  1. Create a displayResults function with results as a parameter. Define a symbol and popupTemplate variable to style and display a pop-up A pop-up is a visual element used to display data for features or graphics in a map. Learn more for polygon graphics A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more . The attributes Attributes are fields and values for a single feature or non-spatial record. They are typically stored in a database or service such as a feature service. Learn more referenced match the outFields specified in the query earlier.

    91 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    queryFeatureLayer(viewElement.extent);
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    parcelLayer
    .queryFeatures(parcelQuery)
    .then((results) => {
    console.log("Feature count: " + results.features.length);
    displayResults(results);
    })
    .catch((error) => {
    console.log(error.error);
    });
    }
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    }
    7 collapsed lines
    </script>
    </body>
    </html>
  2. Assign the symbol and popupTemplate elements to each feature A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more returned from the query.

    110 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    queryFeatureLayer(viewElement.extent);
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    parcelLayer
    .queryFeatures(parcelQuery)
    .then((results) => {
    console.log("Feature count: " + results.features.length);
    displayResults(results);
    })
    .catch((error) => {
    console.log(error.error);
    });
    }
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    // Assign styles and popup to features
    results.features.map((feature) => {
    feature.symbol = symbol;
    feature.popupTemplate = popupTemplate;
    return feature;
    });
    8 collapsed lines
    }
    </script>
    </body>
    </html>
  3. Clear the existing graphics and pop-up A pop-up is a visual element used to display data for features or graphics in a map. Learn more , and then add the new features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more returned to the view.

    101 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    }
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    // Assign styles and popup to features
    results.features.map((feature) => {
    feature.symbol = symbol;
    feature.popupTemplate = popupTemplate;
    return feature;
    });
    // Clear display
    viewElement.closePopup();
    viewElement.graphics.removeAll();
    // Add features to graphics layer
    viewElement.graphics.addMany(results.features);
    9 collapsed lines
    }
    </script>
    </body>
    </html>
  4. Update the queryFeatureLayer function to call the displayResults function. Remove the console.log.

    83 collapsed lines
    <html>
    <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    <title>ArcGIS Maps SDK for JavaScript Tutorials: Query a feature layer (SQL)</title>
    <style>
    html,
    body {
    height: 100%;
    margin: 0;
    }
    </style>
    <script>
    var esriConfig = {
    apiKey: "YOUR_ACCESS_TOKEN",
    };
    </script>
    <!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
    <script type="module" src="https://js.arcgis.com/5.0/"></script>
    </head>
    <body>
    <arcgis-map basemap="arcgis/topographic" center="-118.805, 34.020" zoom="13">
    <arcgis-zoom slot="top-left"></arcgis-zoom>
    <calcite-select id="sqlSelect" slot="top-right">
    <calcite-option id="defaultOption" value="1=0" label="Choose a SQL where clause..."></calcite-option>
    <calcite-option value="UseType = 'Residential'" label="UseType = 'Residential'"></calcite-option>
    <calcite-option value="UseType = 'Government'" label="UseType = 'Government'"></calcite-option>
    <calcite-option value="UseType = 'Irrigated Farm'" label="UseType = 'Irrigated Farm'"></calcite-option>
    <calcite-option value="TaxRateArea = 10853" label="TaxRateArea = 10853"></calcite-option>
    <calcite-option value="TaxRateArea = 10860" label="TaxRateArea = 10860"></calcite-option>
    <calcite-option value="TaxRateArea = 08637" label="TaxRateArea = 08637"></calcite-option>
    <calcite-option value="Roll_LandValue > 1000000" label="Roll_LandValue > 1000000"></calcite-option>
    <calcite-option value="Roll_LandValue < 1000000" label="Roll_LandValue < 1000000"></calcite-option>
    </calcite-select>
    </arcgis-map>
    <script type="module">
    const FeatureLayer = await $arcgis.import("@arcgis/core/layers/FeatureLayer.js");
    const viewElement = document.querySelector("arcgis-map");
    const selectFilter = document.querySelector("#sqlSelect");
    const defaultOption = document.querySelector("#defaultOption");
    let whereClause = defaultOption.value;
    await viewElement.viewOnReady();
    // Event listener
    selectFilter.addEventListener("calciteSelectChange", (event) => {
    whereClause = event.target.value;
    queryFeatureLayer(viewElement.extent);
    });
    // Get query layer and set up query
    const parcelLayer = new FeatureLayer({
    url: "https://services3.arcgis.com/GVgbJbqm8hXASVYi/arcgis/rest/services/LA_County_Parcels/FeatureServer/0",
    });
    function queryFeatureLayer(extent) {
    const parcelQuery = {
    where: whereClause, // Set by select element
    spatialRelationship: "intersects", // Relationship operation to apply
    geometry: extent, // Restricted to visible extent of the map
    outFields: ["APN", "UseType", "TaxRateCity", "Roll_LandValue"], // Attributes to return
    returnGeometry: true,
    };
    parcelLayer
    .queryFeatures(parcelQuery)
    .then((results) => {
    console.log("Feature count: " + results.features.length);
    displayResults(results);
    })
    .catch((error) => {
    console.log(error.error);
    });
    42 collapsed lines
    }
    function displayResults(results) {
    // Create a blue polygon
    const symbol = {
    type: "simple-fill",
    color: [20, 130, 200, 0.5],
    outline: {
    color: "white",
    width: 0.5,
    },
    };
    const popupTemplate = {
    title: "Parcel {APN}",
    content:
    "Type: {UseType} <br> Land value: {Roll_LandValue} <br> Tax Rate City: {TaxRateCity}",
    };
    // Assign styles and popup to features
    results.features.map((feature) => {
    feature.symbol = symbol;
    feature.popupTemplate = popupTemplate;
    return feature;
    });
    // Clear display
    viewElement.closePopup();
    viewElement.graphics.removeAll();
    // Add features to graphics layer
    viewElement.graphics.addMany(results.features);
    }
    </script>
    </body>
    </html>

Run the app

In CodePen, run your code to display the map.

When the map displays, you should be able to choose a SQL query from the selector. The resulting features A feature is a single record, also known as a row, that represents a real-world entity. It typically contains a geometry (point, multipoint, polyline, or polygon) and attributes but it can also contain just attributes. Learn more will be added to the map as polygon graphics A graphic is a visual element composed of a geometry, symbol, and attributes that is displayed on a map or scene. Learn more . The SQL query is applied to the visible extent An extent is a bounding rectangle with points that delineate an area for a map or scene. Learn more of the map.

What’s next?

Learn how to use additional SDK features and ArcGIS services in these tutorials: