Features can be queried based on attribute, location, time. Additionally, you can choose which fields to return, control the sorting order, or calculate statistics.
This sample shows how to use a FeatureLayer to retrieve all features from a feature service when the dataset is too large to load entirely in the client. The layer's queryFeatures() method with pagination retrieves features that exceed the layer’s maxRecordCount limit. A specific number of records are fetched from a designated starting position. Fetched features are displayed in a Calcite List, showing each county's name and median household income. The county features are also highlighted on the map, and clicking a list item zooms to the feature and opens its popup. In this sample, the FeatureLayer shows 2017 median household income data by U.S. counties.
How it works
When the application starts, the total number of features available in the service is retrieved by using the layer's queryFeatureCount() method. This value is then used to determine the total number of pages displayed in the Calcite Pagination component.
// Get number of all features from the service and use the count
// to set the number of pages in the calcite-pagination component
const featureCount = await featureLayer.queryFeatureCount();
document.getElementById("tablePager").setAttribute("total-items", featureCount);
The sample then queries the twenty U.S. counties with the highest median household incomes using the queryFeatures() method. Pagination is achieved by configuring the Query object’s start and num properties:
- The
startproperty specifies the zero-based index indicating where to begin retrieving features. - The
numproperty defines the number of features to fetch in each query.
This approach ensures efficient data retrieval even when the dataset exceeds the layer’s maximum record count limit.
// Fetches 20 features from a specified start location
// Called when the application loads first then it is called whenever
// user changes the page number on the calcite-pagination component
async function queryPage(page) {
// Create the query object honoring layer settings
// sets returnGeometry=true and outFields to "*"
const query = featureLayer.createQuery();
// Set query parameters for pagination and sorting
query.start = page;
query.num = 20;
query.orderByFields = ["MEDHINC_CY DESC"];
const queryResult = await featureLayer.queryFeatures(query);
features = queryResult.features;
convertFeatureSetToRows(features, query);
}
Information about the retrieved counties will be displayed in a Calcite List component located on the right side of the application. The counties in this list will also be visually highlighted on the map.
// Called once next twenty counties are fetched
// and sets up the list items in the calcite-list component
function convertFeatureSetToRows(features, query) {
// Use a local variable for the list node
const incomeList = document.getElementById("incomeList");
incomeList.innerHTML = "";
// Use a DocumentFragment for efficient DOM updates
const fragment = document.createDocumentFragment();
features.forEach((result, index) => {
const { NAME, MEDHINC_CY } = result.attributes;
const item = document.createElement("calcite-list-item");
item.setAttribute("label", NAME);
item.setAttribute("value", index);
item.setAttribute("description", `median income: ${MEDHINC_CY}`);
item.addEventListener("click", onCountyClickHandler);
fragment.appendChild(item);
});
incomeList.appendChild(fragment);
// Safely remove previous highlight and add new one
try {
highlight?.remove();
highlight = layerView.highlight(features, { name: "temporary" });
} catch (error) {
console.error("Highlight error:", error);
}
}
Users can navigate between pages using the pagination controls below the list. The current page number is used to query the corresponding counties sorted by median household income. The following function is executed whenever the Calcite Pagination component’s page number changes.
// Set query.page and fetch the features from the service corresponding
// to the page number when user clicks a page number on calcite-pagination
document.getElementById("tablePager").addEventListener(
"calcitePaginationChange", async (event) => {
// Calculate zero-based page index
const page = event.target.startItem - 1;
try {
await queryPage(page);
// Optionally reset view only if needed
viewElement.zoom = 3;
viewElement.center = [-98, 38];
// Close popup if open
if (popup?.visible) {
viewElement.closePopup();
}
} catch (error) {
console.error("Error updating page:", error);
}
}
);