ESM: import * as reactiveUtils from "@arcgis/core/core/reactiveUtils.js";
CDN: const reactiveUtils = await $arcgis.import("@arcgis/core/core/reactiveUtils.js");
Object: @arcgis/core/core/reactiveUtils
Since: ArcGIS Maps SDK for JavaScript 4.23
reactiveUtils
provide capabilities for observing changes to the state of the SDK's properties, and is an important part of managing your application's life-cycle. State can be observed on a variety of different data types and structures including strings, numbers, arrays, booleans, collections, and objects.
reactiveUtils
provides five methods that offer different patterns and capabilities for observing state: on(), once(), watch(), when() and whenOnce().
The following is a basic example using reactiveUtils.watch(). It demonstrates how to track the Map component updating property and then send a message to the console when the property changes. This snippet uses a getValue
function as an expression that evaluates the updating
property, and when a change is observed the new value is passed to the callback:
// Basic example of watching for changes on a boolean property
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.watch(
// getValue function
() => viewElement.updating,
// callback
(updating) => {
console.log(updating)
});
Working with collections
reactiveUtils
can be used to observe for changes within a collection, such as Map.allLayers. Out-of-the-box JavaScript methods such as .map()
and .filter()
can be used as expressions to be evaluated in the getValue
function.
// Watching for changes within a collection
// whenever a new layer is added to the map
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.watch(
() => viewElement.map.allLayers.map( layer => layer.id),
(ids) => {
console.log(`FeatureLayer IDs ${ids}`);
});
Working with objects
With reactiveUtils
you can track named object properties through dot notation (e.g. viewElement.updating
) or through bracket notation (e.g. viewElement["updating"]
). You can also use the optional chaining operator (?.
). This operator simplifies the process of verifying that properties used in the getValue
function are not undefined
or null
.
// Watch for changes in an object using optional chaining
// whenever the map's extent changes
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.watch(
() => viewElement?.extent?.xmin,
(xmin) => {
console.log(`Extent change xmin = ${xmin}`)
});
WatchHandles and Promises
The watch(), on() and when() methods return a WatchHandle. Be sure remove watch handles when they are no longer needed to avoid memory leaks.
// Use a WatchHandle to stop watching
const viewElement = document.querySelector("arcgis-map");
const handle = reactiveUtils.watch(
() => viewElement?.extent?.xmin,
(xmin) => {
console.log(`Extent change xmin = ${xmin}`)
});
// In another function
handle.remove()
The once() and whenOnce() methods return a Promise instead of a WatchHandle
. In some advanced use cases where an API action may take additional time, these methods also offer the option to cancel the async callback via an AbortSignal
. Be aware that if the returned Promise is not resolved, it can also result in a memory leak.
// Use an AbortSignal to cancel an async callback
// during view animation
const abortController = new AbortController();
// Observe the View's animation state
reactiveUtils.whenOnce(
() => view?.animation, {signal: abortController.signal})
.then((animation) => {
console.log(`View animation state is ${animation.state}`)
});
// Cancel the async callback
const someFunction = () => {
abortController.abort();
}
Working with truthy values
The when() and whenOnce() methods watch for truthy values, these are values that evaluate to true
in boolean contexts. To learn more about using truthy, visit this MDN Web doc article. The snippets below use the Popup.visible property, which is a boolean.
// Observe for changes on a boolean property
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.when(() => viewElement.popup?.visible, () => console.log("Truthy"));
reactiveUtils.when(() => !viewElement.popup?.visible, () => console.log("Not truthy"));
reactiveUtils.when(() => viewElement.popup?.visible === true, () => console.log("True"));
reactiveUtils.when(() => viewElement.popup?.visible !== undefined, () => console.log("Defined"));
reactiveUtils.when(() => viewElement.popup?.visible === undefined, () => console.log("Undefined"));
Method Overview Name Return Type Summary Object on() WatchHandle
Watches the value returned by the getTarget
function for changes and automatically adds or removes an event listener for a given event, as needed.
Promise
Tracks any properties being evaluated by the getValue
function.
Tracks any properties accessed in the getValue
function and calls the callback when any of them change.
Watches the value returned by the getValue
function and calls the callback when it becomes truthy.
Promise
Tracks any properties being evaluated by the getValue
function.
on(getTarget, eventName, callback, options){WatchHandle}
Watches the value returned by the getTarget
function for changes and automatically adds or removes an event listener for a given event, as needed.
Parameters
Function which returns the object to which the event listener is to be added.
The name of the event to add a listener for.
The event handler callback function.
optionalOptions used to configure how the tracking happens and how the callback is to be called.
Returns
Examples
// Adds a click event on a map component when it changes
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.on(
() => viewElement,
"arcgisViewClick",
(event) => {
console.log("arcgisViewClick event emitted: ", event);
});
// Adds a drag event on a map component and adds a callback
// to check when the listener is added and removed.
// Providing `once: true` in the ReactiveListenerOptions
// removes the event after first callback.
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.on(
() => viewElement,
"arcgisViewDrag",
(event) => {
console.log(`Drag event emitted: ${event}`);
},
{
once: true,
onListenerAdd: () => console.log("Drag listener added!"),
onListenerRemove: () => console.log("Drag listener removed!")
});
once(getValue, signal){Promise}
Tracks any properties being evaluated by the getValue
function. When getValue
changes, it returns a promise containing the value. This method only tracks a single change.
Returns
Type Description Promise A promise which resolves when the tracked expression changes.Examples
// Observe for the first time a property equals a specific string value
// Equivalent to watchUtils.once()
reactiveUtils.once(
() => featureLayer.loadStatus === "loaded")
.then(() => {
console.log("featureLayer loadStatus is loaded.");
});
// Use a comparison operator to observe for a first time
// difference in numerical values
const viewElement = document.querySelector("arcgis-map");
const someFunction = async () => {
await reactiveUtils.once(() => viewElement.zoom > 20));
console.log("Zoom level is greater than 20!");
}
// Use a comparison operator and optional chaining to observe for a
// first time difference in numerical values.
reactiveUtils.once(
() => map?.allLayers?.length > 2)
.then((value) => {
console.log(`The map now has ${value} layers.`);
});
watch(getValue, callback, options){WatchHandle}
Tracks any properties accessed in the getValue
function and calls the callback when any of them change.
Returns
Examples
// Watching for changes in a boolean value
// Equivalent to watchUtils.watch()
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.watch(
() => viewELement.popup?.visible,
() => {
console.log(`Popup visible: ${viewELement.popup.visible}`);
});
// Watching for changes within a Collection
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.watch(
() => viewElement.map.allLayers.length,
() => {
console.log(`Layer collection length changed: ${viewElement.map.allLayers.length}`);
});
// Watch for changes in a numerical value.
// Providing `initial: true` in ReactiveWatchOptions
// checks immediately after initialization
// Equivalent to watchUtils.init()
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.watch(
() => viewElement.zoom,
() => {
console.log(`zoom changed to ${viewElement.zoom}`);
},
{
initial: true
});
// Watch properties from multiple sources
const viewElement = document.querySelector("arcgis-map");
const handle = reactiveUtils.watch(
() => [viewElement.stationary, viewElement.zoom],
([stationary, zoom]) => {
// Only print the new zoom value when the map component is stationary
if(stationary){
console.log(`Change in zoom level: ${zoom}`);
}
}
);
when(getValue, callback, options){WatchHandle}
Watches the value returned by the getValue
function and calls the callback when it becomes truthy.
Parameters
Function used to get the current value. All accessed properties will be tracked.
The function to call when the value becomes truthy.
optionalOptions used to configure how the tracking happens and how the callback is to be called.
Returns
Examples
// Observe for when a boolean property becomes not truthy
// Equivalent to watchUtils.whenFalse()
reactiveUtils.when(
() => !layerView.updating,
() => {
console.log("LayerView finished updating.");
});
// Observe for when a boolean property becomes true
// Equivalent to watchUtils.whenTrue()
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.when(
() => viewElement?.stationary === true,
async () => {
console.log("User is no longer interacting with the map");
await drawBuffer();
});
// Observe a boolean property for truthiness.
// Providing `once: true` in ReactiveWatchOptions
// only fires the callback once
// Equivalent to watchUtils.whenFalseOnce()
const featuresComponent = document.querySelector("arcgis-features");
reactiveUtils.when(
() => !featuresComponent.closed,
() => {
console.log(`The features component is closed: ${featuresComponent.closed}`);
},
{
once: true
});
whenOnce(getValue, signal){Promise}
Tracks any properties being evaluated by the getValue
function. When getValue
becomes truthy, it returns a promise containing the value. This method only tracks a single change.
Returns
Type Description Promise A promise which resolves once the tracked expression becomes truthy.Examples
// Check for the first time a property becomes truthy
// Equivalent to watchUtils.whenOnce()
const viewElement = document.querySelector("arcgis-map");
reactiveUtils.whenOnce(
() => viewElement.popup?.visible)
.then(() => {
console.log("Popup used for the first time");
});
// Check for the first time a property becomes not truthy
// Equivalent to watchUtils.whenFalseOnce()
const someFunction = async () => {
await reactiveUtils.whenOnce(() => !layerview.updating);
console.log("LayerView is no longer updating");
}
// Check for the first time a property becomes truthy
// And, use AbortController to potentially cancel the async callback
const abortController = new AbortController();
const viewElement = document.querySelector("arcgis-map");
// Observe the map component's updating state
reactiveUtils.whenOnce(
() => viewElement?.updating, {signal: abortController.signal})
.then((updating) => {
console.log(`Map component's updating state is ${updating.state}`)
});
// Cancel the async callback
const someFunction = () => {
abortController.abort();
}
ReactiveEqualityFunction(newValue, oldValue){Boolean}
Function used to check whether two values are the same, in which case the watch callback isn't called.
Parameters
newValue *
The new value.
oldValue *
The old value.
Returns
Type Description Boolean Whether the new value is equal to the old value. ReactiveListenerChangeCallback(target)
Callback to be called when a event listener is added or removed.
Parameter
target *
optionalThe event target to which the listener was added or from which it was removed.
ReactiveListenerOptions Object
Options used to configure the behavior of reactiveUtils.on.
Default Value:false
Whether to fire the callback synchronously or on the next tick.
optionalDefault Value:false
Whether to fire the callback only once.
optionalCalled when the event listener is added.
optionalCalled when the event listener is removed.
ReactiveOnCallback(event)
Function called to be called when an event is emitted or dispatched.
Parameter
event *
The event emitted by the target.
ReactiveOnExpression(){*}
Function which is auto-tracked and should return an event target to which an event listener is to be added.
Returns
Type Description * The event target. ReactiveWatchCallback(newValue, oldValue)
Function to be called when a value changes.
Parameters
newValue *
The new value.
oldValue *
The old value.
ReactiveWatchExpression(){*}
Function which is auto-tracked and should return a value to pass to the ReactiveWatchCallback
Returns
Type Description * The new value. ReactiveWatchOptions Object
Options used to configure how auto-tracking is performed and how the callback should be called.
Default Value:false
Whether to fire the callback immediately after initialization, if the necessary conditions are met.
optionalDefault Value:false
Whether to fire the callback synchronously or on the next tick.
optionalDefault Value:false
Whether to fire the callback only once.
optionalFunction used to check whether two values are the same, in which case the callback isn't called. Checks whether two objects, arrays or primitive values are shallow equal, e.g. one level deep. Non-plain objects are considered equal if they are strictly equal (===).
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4