<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Query Related Features | Sample | ArcGIS Maps SDK for JavaScript</title>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.0/"></script>
<arcgis-map item-id="00113543095f45e78e521e316dc447dd" popup-disabled>
<arcgis-zoom slot="top-left"></arcgis-zoom>
<arcgis-expand slot="top-right" expand-tooltip="Show Legend">
<arcgis-legend></arcgis-legend>
description="Click on a hexagon in the map to view the cities and their population located in that area.">
<calcite-block id="block">
<div id="query-results"></div>
<calcite-button slot="footer" id="clear-button" style="display: none"
>Clear Query</calcite-button
const viewElement = document.querySelector("arcgis-map");
await viewElement.viewOnReady();
const results = document.getElementById("query-results");
const block = document.getElementById("block");
// Call the clearMap method when clear button is clicked.
const clearbutton = document.getElementById("clear-button");
clearbutton.addEventListener("click", clearMap);
viewElement.addEventListener("arcgisViewClick", (event) => {
queryFeatures(event.detail);
const layer = viewElement.map.layers.at(0);
async function queryFeatures(event) {
// Query the for the feature ids where the user clicked.
const objectIds = await layer.queryObjectIds({
geometry: event.mapPoint,
spatialRelationship: "intersects",
// Highlight the area returned from the first query.
const layerView = await viewElement.whenLayerView(layer);
highlight = layerView.highlight(objectIds);
// Query for the related features for the features ids found.
const relatedFeatureSetByObjectId = await layer.queryRelatedFeatures({
outFields: ["NAME", "SUM_POPULATION"],
relationshipId: layer.relationships[0].id,
if (!relatedFeatureSetByObjectId) {
// Create a Calcite table that will be populated with the related records
const tableComp = document.createElement("calcite-table");
tableComp.caption = "table";
tableComp.interactionMode = "static";
// Create header row for the table
const headerRow = document.createElement("calcite-table-row");
headerRow.slot = "table-header";
relatedFeatureSetByObjectId[Object.keys(relatedFeatureSetByObjectId)[0]].features[0];
// Create headers based on the first feature's attributes
Object.keys(firstFeature.attributes).forEach((key) => {
let tableHeader = document.createElement("calcite-table-header");
tableHeader.heading = key;
headerRow.appendChild(tableHeader);
// Append header row once
tableComp.appendChild(headerRow);
// Populate the table with attribute values from related features
Object.keys(relatedFeatureSetByObjectId).forEach((objectId) => {
const relatedFeatureSet = relatedFeatureSetByObjectId[objectId];
relatedFeatureSet.features.forEach((feature) => {
let tableRow = document.createElement("calcite-table-row");
Object.keys(feature.attributes).forEach((key) => {
let tableCell = document.createElement("calcite-table-cell");
tableCell.textContent = feature.attributes[key];
tableRow.appendChild(tableCell);
// Append each row to the table
tableComp.appendChild(tableRow);
// Append the table to the block.
block.appendChild(tableComp);
// Expand the block and display the clear button when results are displayed.
clearbutton.style.display = "inline";
// Function to clear the highlights from the map and reconfigure the UI
while (block.firstChild) {
block.removeChild(block.firstChild);
clearbutton.style.display = "none";