Watch for changes

Watch for changes in web components

Watching for changes on properties or attributes on a JavaScript Maps SDK component is essential for detecting and implementing custom responses to those changes in your application. You can watch for changes using a component's events, a mutation observer or a proxy. The Watch for changes in components sample demonstrates some of these concepts.

Using component events

Components may emit information about changes to their state as events. The changes can be initiated by internal changes, user interaction or when setting properties or attributes. Listen for events by using the addEventListener method. The event's payload contains information about the change event, such as the action that was triggered, the item that was clicked, or the new state of the component.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
const arcgisLayerList = document.querySelector("arcgis-layer-list");
arcgisLayerList.addEventListener("arcgisTriggerAction", async (event) => {
  // event.detail is used here since the event type is CustomEvent<LayerListTriggerActionEvent>
  // It returns data passed when initializing the event.
  // https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail
  const { action, item } = event.detail;
  await item.layer.load();
  if (action.id === "information") {
    // do something;
  }
});

Map interactions such as panning, zooming, clicking and dragging can be tracked using events. For example, to watch for view-related property changes, such as zoom, on the arcgis-map component, use the arcgisViewChange event.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
const mapElement = document.querySelector("arcgis-map");
mapElement.addEventListener("arcgisViewChange", (event) => {
  // event.target provides a reference to the object that dispatched the event
  // event.target is used here since the event type is CustomEvent<void>
  // The void means that there are no details provided by the event, itself.
  const { zoom } = event.target;
  console.log(`The zoom is ${zoom}`);
})

The arcgisViewReadyChange event is particularly useful for detecting when a Map, WebMap or WebScene has been initially loaded or updated on the arcgis-map or arcgis-scene component. Here are the scenarios that trigger arcgisViewReadyChange:

  • Initial load: When the arcgis-map or arcgis-scene component's map is initially set, the event will fire once the view is ready.
  • Updates: If the map of a map or scene component is replaced with either a Map, WebMap, or WebScene, the event will fire again. Changing the item-id will also trigger the event, signaling that a new WebMap or WebScene has been loaded.
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
const map = document.querySelector("arcgis-map");

map.addEventListener("arcgisViewReadyChange", () => {
  console.log(`New WebMap loaded with itemId: ${map.itemId}`);
  // Perform actions based on the newly loaded WebMap
});

// Example of switching the WebMap after a delay
setTimeout(() => {
  map.itemId = "new-webmap-id";
}, 3000);

The arcgisPropertyChange event allows for the monitoring of property changes in non-view-based components. For instance, in the arcgis-area-measurement-2d component, the arcgisPropertyChange event can be used to track the state of the measurement process, such as when a user initiates or completes a measurement.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
const areaMeasurement = document.querySelector("arcgis-area-measurement-2d");

areaMeasurement.addEventListener("arcgisPropertyChange", (e) => {
  if (e.detail.name === "state") {
    console.log("Measurement state:", e.target[e.detail.name]);
  }
});

Using a mutation observer

A mutation observer is useful for watching changes that are reflected on the DOM tree. JavaScript objects and arrays cannot be watched with a mutation observer because they are not part of the DOM, and not every attribute on a component is reflected, meaning that not every attribute will trigger a mutation observer.

The observer approach allows for efficient tracking of mutations over the entire DOM tree, without needing an event listener. Observers use weak references to DOM nodes, so when nodes are removed they can be garbage collected. And, you can also continue to observe disconnected DOM nodes.

Changes that are reflected on the DOM can be visibly observed in a browser's developer tools. One example is when a map is panned, the arcgis-map component's updating attribute will appear for a few seconds.

Before panning the map:

Use dark colors for code blocksCopy
1
<arcgis-map item-id="05e015c5f0314db9a487a9b46cb37eca"></arcgis-map>

During panning the map:

Use dark colors for code blocksCopy
1
<arcgis-map item-id="05e015c5f0314db9a487a9b46cb37eca" updating></arcgis-map>

In the example below, the mutation observer will fire a callback function when any of the arcgis-map component's attributes are modified by the application or the component.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
const mapElement = document.querySelector("arcgis-map");
const observer = new MutationObserver((mutations, observer) => {
  for (let mutation of mutations) {
    console.log(`Mutation observer: ${mutation.attributeName} changed to ${mutation.target[mutation.attributeName]}`);
  }
});

// Start observing the map's attributes for changes, such as the updating property
observer.observe(mapElement, { attributeFilter: ["updating"] });

// Change the zoom level after 10 seconds
setTimeout(() => {
  mapElement.zoom = 7;
}, "10000");

The References for Maps SDK components list the properties that are reflected on the DOM and can be watched with a mutation observer.

Using a proxy

A proxy is useful for observing or trapping changes your application makes programmatically to a component's properties before the component can act on them. In the example below, the proxy will fire a callback function when any of the arcgis-map component's properties are modified. The set method only applies to properties that you explicitly set in your code. When these changes are trapped, they are essentially intercepted and you can take any action you want before passing on the new value or modifying it in some way. You can also read more about Proxy at javascript.info.

Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  const mapElement = document.querySelector("arcgis-map");

  // A handler for the proxy to define which operations will be intercepted
  // and how to redefine them
  const handler = {
    // obj - the object being proxied (in this case, the map)
    // prop - the property of the object that is being set
    // value - the new value of the property
    set(obj,prop,value) {
      obj[prop] = value; // set property to new value
      console.log(`Proxy: the ${prop} property was changed to ${value}`);
      return true;
    }
  }

  // Initialize the new proxy
  let proxy = new Proxy(mapElement, handler);

  // Change to a different basemap and zoom level
  const changeBasemap = () => {
    proxy.zoom = 7;
    proxy.basemap = "streets-vector";
  }

Watch for changes in the API

reactiveUtils provides the ability to track changes in API properties with a variety of different data types and structures, such as strings, booleans, arrays, collections, and objects. The module also allows for combining properties from multiple sources. It includes the following methods: watch(), on(), once(), when(), and whenOnce().

reactiveUtils also provide TypeScript type checking. You can access properties, build objects or perform other calculations and it is all properly checked by the TypeScript compiler. Callback parameters are also correctly inferred from the getValue function.

To see reactiveUtils in action, you can explore these samples:

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.