ArcGIS Map Components Release
Introduction
A few years ago, I demoed a prototype of web components using the ArcGIS Maps SDK for JavaScript to my colleagues – which at the time was called the ArcGIS API for JavaScript – that’s five extra keystrokes if you’re keeping track. It was just an idea and believe me – I have plenty of ideas. It was something that had the potential to be beneficial to users and other developers at Esri. For current users, it could simplify how much code they need to write and take advantage of components to write basic applications. They can also be a gentle introduction to the maps SDK using HTML and CSS with minimal JavaScript. I knew there was other web component work being done – of course Calcite Components, and applications such as the Map Viewer, Instant Apps, and more were using web components to make it easier to reuse components in applications. I was lucky enough to have a spark at the right time and join a team with a goal to make it easier for internal developers to not only use web components – but to build their own.
At Developer Summit 2024, the Map components were announced as a beta release. This was a huge step above the initial crude implementation, but with the help of a solid team, we were able to get them in a good spot. More importantly, we were able to get more developers testing and providing feedback. With the help of that feedback, as of the 4.30 release of the ArcGIS Maps SDK for JavaScript, the map components are now officially out of beta. This means a defined API, naming convention, and they should work as advertised. Are they perfect? Sounds like a philosophical question to me, but they are stable. There is of course what we would call under-the-hood work to be done. There are plans to have additional web component features in a future release. I’m not a fortune-teller though, so don’t ask me when – but when they are added you will know.
Map Components
What are the map components? They are a collection of custom elements that let you compose HTML to build an application. In many cases you only need an item id for a webmap or webscene from ArcGIS Online or your own Enterprise portal. You may not even need to write JavaScript. The components can be used almost anywhere. The advantage is they are portable across applications and tooling.
Things to know
Here are a few things I think you should know when working with components.
1. Events
In the map components, we can make a distinction between view components and UI components. View components would be the arcgis-map
and arcgis-scene
. These two components are the equivalent of the MapView
and SceneView
in the core API. I only bring this up because these two components have a specific event called arcgisViewReadyChange
.
const mapElement = document.querySelector("arcgis-map");
mapElement.addEventListener("arcgisViewReadyChange", (event) => {
// Continue work that might include adding layers or more
});
This event will fire when the component is ready to be used. If you have ever used view.when()
with the core API, that’s how this works. This event only fires once – unless you change the map
property. Yes, you can do that.
// Assign a WebMap to a Map Component
// Using CDN, similar with NPM package
const arcgisMap = document.querySelector("arcgis-map");
async function load() {
// Change the WebMap
const WebMap = await $arcgis.import("esri/WebMap");
arcgisMap.map = new WebMap({
portalItem: { id: "e691172598f04ea8881cd2a4adaa45ba" }
});
}
load();
// You can defer loading components to do
// authentication for example
async function load() {
const IdentityManager = await $arcgis.import("esri/identity/IdentityManager");
const OAuthInfo = await $arcgis.import("esri/identity/OAuthInfo");
// Do your authentication steps here
// When ready, load the components library and it will pick up
// the authentication you have done.
await import("https://js.arcgis.com/map-components/4.30/arcgis-map-components.esm.js");
}
load();
Another event that is common across all components is arcgisPropertyChange
. Before I dive into this event, you need to remember that custom elements are a standard and there are standard ways to know when DOM elements have changed. Event listeners and Mutation Observers. If you have used the core API, you are probably familiar with the Accessor and watching for property changes. This is a convenient pattern – in the core API. For custom elements, not so much. There was quite a bit of discussion on whether we should implement a DOMReactiveUtils
that would work just on map components. But this isn’t part of the standard, it wouldn’t work anywhere else except map components and honestly, goes against the grain of the web platform.
What does this have to do with arcgisPropertyChange
? This event will fire when some properties on a component change. This lets you do something in your application that might need to know when a property has changed. When this event fires it will provide the name of the property that changed, and you can then access that value from the component.
const features = document.querySelector("arcgis-features");
features.addEventListener("arcgisPropertyChange", (event) => {
// name: event.detail.name
// value: features[event.detail.name]
});
Some properties are also attributes (more on that in a moment). What makes a property an attribute? It must be either a boolean, string, or number. But if the updates are reflected to the element, you can use a MutationObserver.
An event like arcgisViewReadyChange
that is available on UI components is arcgisReady
. This means the component is ready. I’ve written a lot of test apps and so far, I haven’t used this event, but it’s there in case you need it – someone will.
2. Attributes and Properties
With HTML elements, it’s key to understand the difference between attribute and properties. This topic can cause confusion for developers when trying to set properties as attributes or expecting certain value types when accessing properties.
Let’s start with attributes. Attributes are values that can be set directly in the DOM on an element. Here are some examples.
<input type="text" value="Bob" />
<button type="submit">Submit</button>
<my-element show-children origin="home"></my-element>
Technically, all attributes are only string values. Even a boolean value is either null
or an empty string ""
. Technically it is truthy or falsey. What could possibly go wrong here?
Attributes are also always kebab-case. Don’t try to set showChildren
as an attribute on the custom element, the proper name is show-children
.
You can access attributes via element.getAttribute("value")
and set attributes via element.setAttribute("value")
. For boolean attributes, you can use element.toggleAttribute("show-children")
.
Properties however can only be accessed via JavaScript: console.log(element.currentValue)
. Properties cannot be set as attributes, but that doesn’t mean they can’t be related. A property can also be an alias for attribute and vice versa.
You might have a property called valueHistory
that is an array that tracks value
attribute changes. This property can be accessed internally by the component or by users that might be interested in using these entries in their application.
The key here is that properties can be objects or arrays. Attributes can be string, number, or boolean.
3. Frameworks
Events and property/attribute assignment are some core basics you should know when working with not only components, but the DOM in general. But you can also use libraries and frameworks to make this easier to deal with. For example, in React, you can assign complex objects to components.
<ArcgisMap
itemId="d5dda743788a4b0688fe48f43ae7beb9"
popup={
{
dockEnabled: true,
dockOptions: {
position: "bottom-right",
breakpoint: false,
},
}
}
theme={
{
accentColor: "purple",
textColor: [125, 255, 13, 0.9],
}
}
onArcgisViewReadyChange={() => {
console.log("Map is ready");
}}
>
<ArcgisSearch position="top-right" />
<ArcgisExpand position="bottom-left">
<ArcgisAreaMeasurement2d />
</ArcgisExpand>
</ArcgisMap>
All those rules about property assignment and objects mentioned earlier can be thrown out the window when talking about most frameworks. They will handle correct property assignment for you.
In a DevSummit presentation, I did a quick rundown showing how you can use them with everything from React to Laravel, even an Elm application. Some may have thought I went too far – I like to think I went far enough. The components provide framework wrappers for React and Angular. But with upcoming release of React 19, you shouldn’t need the wrapper.
// Example using React 19
import { defineCustomElements } from "@arcgis/map-components/dist/loader";
import './App.css';
defineCustomElements();
function App() {
const popupConfig = {
dockEnabled: true,
dockOptions: {
position: "bottom-right",
breakpoint: false,
},
};
return (
<div className='app-container'>
<arcgis-map
popup={popupConfig}
item-id="e691172598f04ea8881cd2a4adaa45ba"
onarcgisViewReadyChange={() => console.log("ready")}></arcgis-map>
</div>
)
}
export default App
Samples
In addition to the documentation, patterns and tutorials, there are more samples you can review here. These samples provide a good starting point. You will notice that hanging out among React and Vue samples is a CDN sample. It’s important to note that the CDN is a completely viable way to build some applications. You don’t always need a framework. You don’t always need a build tool. Sometimes you just need some HTML and a dash of CSS. I’m a fan of simplicity.
Summary
The addition of components to the ArcGIS Maps SDK for JavaScript provides some new options and powerful features to developers. The intention is that it makes adding mapping capabilities to your applications easier and provides some reusability. With a script and link tag, you can add maps to a WordPress site, Shopify store or any other static page without having to worry about writing additional JavaScript. And for new users who want to display a map quickly on the page, they can focus on other capabilities of the SDK like queries and visualization.