@arcgis/core 5.2.0-next.14 → 5.2.0-next.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/esri/core/workers/RemoteClient.js +1 -1
- package/assets/esri/core/workers/chunks/{31762eb20a9a0ed3f8b0.js → 011a4d4201696fa10408.js} +1 -1
- package/assets/esri/core/workers/chunks/01ba5319cac3e0f14205.js +1 -0
- package/assets/esri/core/workers/chunks/0436fe89adc78696251c.js +1 -0
- package/assets/esri/core/workers/chunks/079b412d07d02504f1db.js +1 -0
- package/assets/esri/core/workers/chunks/{38cfedce779dd75bd217.js → 07ca020796c57cefda62.js} +1 -1
- package/assets/esri/core/workers/chunks/0b45d34938fa7862f746.js +1 -0
- package/assets/esri/core/workers/chunks/{a4b970a841b3085500fc.js → 0b55fc5050e718371e05.js} +1 -1
- package/assets/esri/core/workers/chunks/{97a654e8054302582a3b.js → 0bf72e9d0a6deceeb406.js} +1 -1
- package/assets/esri/core/workers/chunks/11c3b1e8ca21ad62fdd1.js +1 -0
- package/assets/esri/core/workers/chunks/1bd49e8d2657c72bf3f9.js +1 -0
- package/assets/esri/core/workers/chunks/1d81e667a580c5cdeda1.js +262 -0
- package/assets/esri/core/workers/chunks/25c1f5e2561986330b80.js +1 -0
- package/assets/esri/core/workers/chunks/2bc4aff77c830061e16e.js +1 -0
- package/assets/esri/core/workers/chunks/{8c443c52c846a096a250.js → 36dd3ad3ef2fbfc15cbd.js} +1 -1
- package/assets/esri/core/workers/chunks/39a10b2092a98083f4cf.js +1 -0
- package/assets/esri/core/workers/chunks/3bd32387af52fa48d747.js +1 -0
- package/assets/esri/core/workers/chunks/3dc6e9494af16f7b8009.js +1 -0
- package/assets/esri/core/workers/chunks/42e5e00610f281ca8ffa.js +1 -0
- package/assets/esri/core/workers/chunks/{73c355b895fd6a34fcb8.js → 45b560ca01fb566ba560.js} +1 -1
- package/assets/esri/core/workers/chunks/47d630561f3fce5c63c4.js +1 -0
- package/assets/esri/core/workers/chunks/4cc78493805671708a9b.js +1 -0
- package/assets/esri/core/workers/chunks/4e59e5a5d0ff887ff899.js +1 -0
- package/assets/esri/core/workers/chunks/4efef5fa8bf23aaf34cd.js +1 -0
- package/assets/esri/core/workers/chunks/511b9c12a7479d39dac0.js +1 -0
- package/assets/esri/core/workers/chunks/{20c729fca2e4b4c6b28d.js → 57b7e5fde972d3ad7884.js} +1 -1
- package/assets/esri/core/workers/chunks/57e04b7ec238f7b24274.js +1 -0
- package/assets/esri/core/workers/chunks/5d8924fdcdb473d261cd.js +1 -0
- package/assets/esri/core/workers/chunks/62de9e83331fb10aac6a.js +2 -0
- package/assets/esri/core/workers/chunks/{854c320af09b6afc4b80.js → 641cddee377599916de2.js} +2 -2
- package/assets/esri/core/workers/chunks/65cc9a48ac95523f7aa8.js +1 -0
- package/assets/esri/core/workers/chunks/66392ff750c28064040a.js +1 -0
- package/assets/esri/core/workers/chunks/668d84dc512b3085a960.js +1 -0
- package/assets/esri/core/workers/chunks/{318a2702632aaa4d3a63.js → 6a1b6f8c868f8edce1d7.js} +1 -1
- package/assets/esri/core/workers/chunks/6f5a82388a5eb5fcf1b7.js +1 -0
- package/assets/esri/core/workers/chunks/73b0edabddbb72fe1104.js +1 -0
- package/assets/esri/core/workers/chunks/7ee76504e7fea389a1c9.js +1 -0
- package/assets/esri/core/workers/chunks/7f849c8255140be6097f.js +1 -0
- package/assets/esri/core/workers/chunks/8927fb4aa68f7e541a39.js +30 -0
- package/assets/esri/core/workers/chunks/8eda85fc01a71aedd9e4.js +1 -0
- package/assets/esri/core/workers/chunks/8f25d91ea7b99597124e.js +1 -0
- package/assets/esri/core/workers/chunks/92341f36a8b15f34bcca.js +1 -0
- package/assets/esri/core/workers/chunks/9f93c29af2a18f7cb160.js +1 -0
- package/assets/esri/core/workers/chunks/a18cb809dd56c5537b3b.js +1 -0
- package/assets/esri/core/workers/chunks/a4f3bcfabd4ad127abf2.js +1 -0
- package/assets/esri/core/workers/chunks/a63bba226de6c5e464b0.js +1 -0
- package/assets/esri/core/workers/chunks/{7dcf804e1918b94fa4e1.js → a98905bf6050ad3b8721.js} +1 -1
- package/assets/esri/core/workers/chunks/a9f29ff36a7ae5bae686.js +1 -0
- package/assets/esri/core/workers/chunks/{1d5db8746a4f1ed1d18f.js → b102beeeb7a919f68b51.js} +1 -1
- package/assets/esri/core/workers/chunks/b75a4753cea6544da8bb.js +1 -0
- package/assets/esri/core/workers/chunks/bd36c57dd0cd28dee55f.js +30 -0
- package/assets/esri/core/workers/chunks/c8460bdf60aca749ed05.js +30 -0
- package/assets/esri/core/workers/chunks/c9057b0ad2c2bae4a8ce.js +1 -0
- package/assets/esri/core/workers/chunks/e73bb7c8de7412d9975c.js +1 -0
- package/assets/esri/core/workers/chunks/e8546ab510fc9515bd23.js +1 -0
- package/assets/esri/core/workers/chunks/e9acc05b0cf9e05f31a8.js +1 -0
- package/assets/esri/core/workers/chunks/{e77df11aee136d64ff0f.js → eb91dc957c328674e119.js} +1 -1
- package/assets/esri/core/workers/chunks/{0a8ba5cb857f61de40fb.js → ed2a1c371dfc5d4a744e.js} +28 -28
- package/assets/esri/core/workers/chunks/f0832b413612c77a62ca.js +1 -0
- package/assets/esri/core/workers/chunks/f955b35337a08f9f747d.js +1 -0
- package/assets/esri/core/workers/chunks/fea3b6bef761ef78630e.js +1 -0
- package/assets/esri/libs/lyr3d/lyr3DMain.wasm +0 -0
- package/assets/esri/views/3d/analysis/ShadowCast/t9n/ShadowCastAnalysis_fr.json +1 -1
- package/chunks/Component.glsl.js +3 -3
- package/chunks/GaussianSplatComposition.glsl.js +1 -1
- package/chunks/GlobalIlluminationBlur.glsl.js +11 -11
- package/chunks/OITBlend.glsl.js +1 -24
- package/chunks/OITBlendEmission.glsl.js +9 -9
- package/chunks/OITDimOpaque.glsl.js +3 -9
- package/chunks/lyr3DMain.js +1 -1
- package/config.js +1 -1
- package/core/reactiveUtils.d.ts +410 -109
- package/kernel.js +1 -1
- package/layers/Lyr3DWasmPerSceneView.js +1 -1
- package/layers/graphics/sources/MemorySource.js +1 -1
- package/layers/mixins/OperationalLayer.js +1 -1
- package/layers/support/ExportImageServiceParameters.js +1 -1
- package/layers/support/layersMapping.js +1 -1
- package/package.json +3 -3
- package/rest/print.js +1 -1
- package/support/revision.js +1 -1
- package/views/2d/engine/webgl/TextureManager.js +1 -1
- package/views/2d/engine/webgl/shaderGraph/techniques/vectorTiles/VTLTechniqueBackground.js +1 -1
- package/views/2d/engine/webgl/shaders/sources/shaderRepository.js +1 -1
- package/views/3d/interactive/visualElements/DrapedVisualElementResources.js +1 -1
- package/views/3d/layers/graphics/Graphics3DIconSymbolLayer.js +1 -1
- package/views/3d/webgl-engine/core/shaderLibrary/shading/Gamma.glsl.js +2 -2
- package/views/3d/webgl-engine/core/shaderLibrary/util/EmissionDimming.glsl.js +1 -1
- package/views/3d/webgl-engine/core/shaderTechnique/ShaderTechniqueRepository.js +1 -1
- package/views/3d/webgl-engine/effects/fog/FogTechniqueConfiguration.js +1 -1
- package/views/3d/webgl-engine/effects/globalIllumination/GlobalIlluminationBlur.glsl.js +1 -1
- package/views/3d/webgl-engine/effects/glow/Glow.js +1 -1
- package/views/3d/webgl-engine/effects/glow/GlowBlurTechniqueConfiguration.js +1 -1
- package/views/3d/webgl-engine/effects/glow/GlowCompositionTechniqueConfiguration.js +1 -1
- package/views/3d/webgl-engine/effects/smaa/SMAA.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlend.glsl.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlend.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlendEmission.glsl.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlendEmissionTechnique.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlendFragmentTechniqueConfiguration.js +2 -0
- package/views/3d/webgl-engine/effects/transparency/OITBlendTechnique.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlendTechniqueConfiguration.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITDimOpaque.glsl.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/OITDimOpaqueTechnique.js +1 -1
- package/views/3d/webgl-engine/effects/transparency/oitBlendFragment.glsl.js +2 -0
- package/views/3d/webgl-engine/lib/GaussianSplatRenderNode.js +1 -1
- package/views/3d/webgl-engine/lib/Material.js +1 -1
- package/views/3d/webgl-engine/lib/Renderer.js +1 -1
- package/views/3d/webgl-engine/lib/lodRendering/LodComponentData.js +1 -1
- package/views/3d/webgl-engine/lib/lodRendering/LodLevel.js +1 -1
- package/views/3d/webgl-engine/lib/lodRendering/LodRenderer.js +1 -1
- package/views/3d/webgl-engine/materials/ColorMaterial.js +1 -1
- package/views/3d/webgl-engine/materials/DefaultMaterial.js +1 -1
- package/views/3d/webgl-engine/materials/PathMaterial.js +1 -1
- package/views/3d/webgl-engine/materials/PatternMaterial.js +1 -1
- package/views/3d/webgl-engine/materials/RibbonLineMaterial.js +1 -1
- package/views/3d/webgl-engine/materials/renderers/MergedRenderer.js +1 -1
- package/views/3d/webgl-engine/shaders/GaussianSplatCompositionTechniqueConfiguration.js +1 -1
- package/views/3d/webgl-engine/shaders/OutputColorHighlightOLID.glsl.js +1 -1
- package/views/3d/webgl-engine/shaders/oitResolution.glsl.js +1 -1
- package/views/View2D.d.ts +2 -3
- package/webdoc/support/writeUtils.js +1 -1
- package/widgets/Editor.js +1 -1
- package/widgets/Print/PrintViewModel.d.ts +11 -1
- package/widgets/Print/PrintViewModel.js +1 -1
- package/assets/esri/core/workers/chunks/0cbd7f5fe24271942abd.js +0 -1
- package/assets/esri/core/workers/chunks/1a95370ddc22729ab3c6.js +0 -1
- package/assets/esri/core/workers/chunks/2185e8a52c5e29d46680.js +0 -1
- package/assets/esri/core/workers/chunks/23d50c4478f40a7d62bf.js +0 -1
- package/assets/esri/core/workers/chunks/2623cd08487fdc9a94f1.js +0 -1
- package/assets/esri/core/workers/chunks/26583db2af1a1cc456e5.js +0 -1
- package/assets/esri/core/workers/chunks/2b00229c238aae70b948.js +0 -1
- package/assets/esri/core/workers/chunks/2b814bb51704a5b4fdc2.js +0 -30
- package/assets/esri/core/workers/chunks/30f1909c5ef1835b8507.js +0 -1
- package/assets/esri/core/workers/chunks/3172d7fc23787a287191.js +0 -1
- package/assets/esri/core/workers/chunks/39596715e84d0da2f803.js +0 -30
- package/assets/esri/core/workers/chunks/398eb3100a282e4736bb.js +0 -1
- package/assets/esri/core/workers/chunks/426b8e1e2eef2460851d.js +0 -1
- package/assets/esri/core/workers/chunks/4376bc2934a996d8bc27.js +0 -1
- package/assets/esri/core/workers/chunks/44e52fe98ffafe6a2807.js +0 -1
- package/assets/esri/core/workers/chunks/4d09ef7c57ab7f9782fe.js +0 -1
- package/assets/esri/core/workers/chunks/5022413f5a41b5d435ea.js +0 -1
- package/assets/esri/core/workers/chunks/5201105ca11a2d450460.js +0 -1
- package/assets/esri/core/workers/chunks/528ed0bd8dc149ead023.js +0 -1
- package/assets/esri/core/workers/chunks/59dafa1e1340ea4043e6.js +0 -1
- package/assets/esri/core/workers/chunks/684d3cb4fb233180b2d0.js +0 -1
- package/assets/esri/core/workers/chunks/6d616b66fb32904b55a1.js +0 -1
- package/assets/esri/core/workers/chunks/6d696beddcc5fbed5875.js +0 -1
- package/assets/esri/core/workers/chunks/6f125b4ed06c0022dee6.js +0 -1
- package/assets/esri/core/workers/chunks/6f4825c3ef1fe202ab82.js +0 -1
- package/assets/esri/core/workers/chunks/6f7193b9ff5942c0d354.js +0 -1
- package/assets/esri/core/workers/chunks/70737052bab29fcaa120.js +0 -1
- package/assets/esri/core/workers/chunks/72d67cc3a382e83bf1a2.js +0 -1
- package/assets/esri/core/workers/chunks/851705cf276eae8d4d37.js +0 -1
- package/assets/esri/core/workers/chunks/882ee7ed8a3a0215f9b9.js +0 -1
- package/assets/esri/core/workers/chunks/9d5f7573bfe3b051daf1.js +0 -1
- package/assets/esri/core/workers/chunks/a0c00c6fe60db49b3ab9.js +0 -1
- package/assets/esri/core/workers/chunks/af31e62499d45bdab3c3.js +0 -1
- package/assets/esri/core/workers/chunks/b9935cc8e2bd4045058a.js +0 -1
- package/assets/esri/core/workers/chunks/bdc66ef2b6ed783047d5.js +0 -1
- package/assets/esri/core/workers/chunks/c2a65de34f6a6c89c652.js +0 -1
- package/assets/esri/core/workers/chunks/c424a66f1546275e2bcb.js +0 -30
- package/assets/esri/core/workers/chunks/d2f47f21ce0b0ab4da17.js +0 -262
- package/assets/esri/core/workers/chunks/d5c35a75fd4c41def420.js +0 -1
- package/assets/esri/core/workers/chunks/dbd2bfcbf3e0f86f07b8.js +0 -1
- package/assets/esri/core/workers/chunks/df54e741db40b308c2dd.js +0 -2
- package/assets/esri/core/workers/chunks/e33d2ede6c9f1527d51b.js +0 -1
- package/assets/esri/core/workers/chunks/e912b515704e20313e53.js +0 -1
- package/assets/esri/core/workers/chunks/eac683a37339aa558455.js +0 -1
- package/assets/esri/core/workers/chunks/f590db684d88e72bd79b.js +0 -1
- package/assets/esri/core/workers/chunks/fa3faec65882c5b6f1a0.js +0 -1
- package/views/3d/webgl-engine/effects/transparency/OITBlendEmissionTechniqueConfiguration.js +0 -2
- package/views/3d/webgl-engine/effects/transparency/OITDimOpaqueTechniqueConfiguration.js +0 -2
- /package/assets/esri/core/workers/chunks/{df54e741db40b308c2dd.js.LICENSE.txt → 62de9e83331fb10aac6a.js.LICENSE.txt} +0 -0
- /package/assets/esri/core/workers/chunks/{854c320af09b6afc4b80.js.LICENSE.txt → 641cddee377599916de2.js.LICENSE.txt} +0 -0
package/core/reactiveUtils.d.ts
CHANGED
|
@@ -1,139 +1,429 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* * [Overview](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#overview)
|
|
3
3
|
* * [Using reactiveUtils](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#using-reactiveutils)
|
|
4
|
+
* * [Truthy checks versus explicit value checks](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#truthy-values)
|
|
5
|
+
* * [Async versus sync callbacks](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#async-vs-sync)
|
|
4
6
|
* * [Working with collections](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#working-with-collections)
|
|
5
7
|
* * [Working with objects](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#working-with-objects)
|
|
6
|
-
* * [
|
|
7
|
-
* * [Working with
|
|
8
|
+
* * [ResourceHandles and Promises](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#resourcehandles-and-promises)
|
|
9
|
+
* * [Working with TypeScript](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#typescript)
|
|
8
10
|
*
|
|
9
11
|
* <span id="overview"></span>
|
|
10
12
|
* ## Overview
|
|
11
|
-
* `reactiveUtils`
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
13
|
+
* `reactiveUtils` provides a declarative way to watch SDK state and respond to changes.
|
|
14
|
+
*
|
|
15
|
+
* To use it, provide:
|
|
16
|
+
* - A reactive expression that returns the state you want to track.
|
|
17
|
+
* - A callback that runs whenever that state changes.
|
|
18
|
+
*
|
|
19
|
+
* The reactive expression is a function that automatically re-evaluates whenever any state it accesses changes.
|
|
20
|
+
* For example, if the expression reads the map component's `stationary` property,
|
|
21
|
+
* the callback runs whenever `stationary` changes between `true` and `false`.
|
|
22
|
+
*
|
|
23
|
+
* Reactive expressions can track primitive values, arrays, collections, and objects.
|
|
24
|
+
* Depending on the function you use, `reactiveUtils` supports both continuous observation and one-time conditions.
|
|
15
25
|
*
|
|
16
26
|
* <span id="using-reactiveutils"></span>
|
|
17
27
|
* ## Using reactiveUtils
|
|
18
28
|
*
|
|
19
|
-
* `reactiveUtils` provides five
|
|
29
|
+
* `reactiveUtils` provides five functions for observing state:
|
|
20
30
|
* [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on), [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once), [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch), [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce).
|
|
31
|
+
* Each of these has different characteristics and use cases, as summarized in the table below:
|
|
32
|
+
*
|
|
33
|
+
* | Function | Runs multiple times | Resolves once | Returns | Common use |
|
|
34
|
+
* | ----------------------------------- | ------------------- | ------------- | ---------------- | ------------------------------------ |
|
|
35
|
+
* | [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch) | Yes | No | `ResourceHandle` | Continuously observe for changes |
|
|
36
|
+
* | [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) | Yes | No | `ResourceHandle` | Run when expression becomes truthy |
|
|
37
|
+
* | [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on) | Yes | No | `ResourceHandle` | Observe events |
|
|
38
|
+
* | [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) | No | Yes | `Promise` | Wait for first emitted value |
|
|
39
|
+
* | [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) | No | Yes | `Promise` | Wait until expression becomes truthy |
|
|
21
40
|
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
41
|
+
* <details>
|
|
42
|
+
* <summary>Read More</summary>
|
|
43
|
+
*
|
|
44
|
+
* The snippet below uses [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch) to react when the
|
|
45
|
+
* Map component's [stationary](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#stationary) property changes.
|
|
46
|
+
* This pattern is useful when work should run after navigation settles, such as querying
|
|
47
|
+
* features for the current extent, refreshing summary statistics, or enabling UI actions.
|
|
48
|
+
*
|
|
49
|
+
* The first argument in the `watch()` function is the reactive expression, in the form of a `getValue` function, that evaluates the
|
|
50
|
+
* `stationary` property. When a change is observed in the expression the new value is automatically passed to the callback:
|
|
26
51
|
*
|
|
27
52
|
* ```js
|
|
28
|
-
* //
|
|
53
|
+
* // Watching for changes on the map component's stationary property
|
|
29
54
|
* const viewElement = document.querySelector("arcgis-map");
|
|
30
|
-
* reactiveUtils.watch(
|
|
31
|
-
* // getValue
|
|
32
|
-
* () => viewElement.
|
|
55
|
+
* const handle = reactiveUtils.watch(
|
|
56
|
+
* // getValue expression
|
|
57
|
+
* () => viewElement.stationary,
|
|
33
58
|
* // callback
|
|
34
|
-
* (
|
|
35
|
-
* console.log(
|
|
59
|
+
* (stationary) => {
|
|
60
|
+
* console.log(stationary)
|
|
36
61
|
* });
|
|
62
|
+
*
|
|
63
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
64
|
+
* handle.remove();
|
|
65
|
+
* ```
|
|
66
|
+
*
|
|
67
|
+
* Other examples of `getValue` expressions include:
|
|
68
|
+
*
|
|
69
|
+
* ```js
|
|
70
|
+
* () => viewElement.ready // Wait until the view finishes updating
|
|
71
|
+
* () => [viewElement.stationary, viewElement.zoom] // Track changes to multiple properties at once
|
|
72
|
+
* () => viewElement.popupElement?.open // Detect when a popup is opened
|
|
73
|
+
* () => layer.visible // Track changes in layer visibility
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* **Basic usage rules:**
|
|
77
|
+
* - Shape expressions so callbacks receive defined values.
|
|
78
|
+
* - Avoid truthy checks when falsy values like `0`, `""`, or `false` are valid.
|
|
79
|
+
* - Use explicit comparisons for specific values (e.g., `=== 0` or `=== false`).
|
|
80
|
+
* - Use optional chaining (`?.`) to safely access nested properties.
|
|
81
|
+
* - Return derived values for collections to react to structural changes.
|
|
82
|
+
*
|
|
83
|
+
* </details>
|
|
84
|
+
*
|
|
85
|
+
* <span id="truthy-values"></span>
|
|
86
|
+
* ### Truthy checks versus explicit value checks
|
|
87
|
+
*
|
|
88
|
+
* The [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) functions execute when the `getValue` expression
|
|
89
|
+
* evaluates as truthy, instead of reacting to every value change.
|
|
90
|
+
*
|
|
91
|
+
* Use [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) checks when you only care whether a value is present or available.
|
|
92
|
+
* Use [explicit value](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Equality_comparisons_and_sameness) checks
|
|
93
|
+
* when you need to verify a specific state or distinguish between different values.
|
|
94
|
+
*
|
|
95
|
+
* | Goal | Recommended approach |
|
|
96
|
+
* | ------------------------------------- | -------------------- |
|
|
97
|
+
* | Wait for property existence | Truthy |
|
|
98
|
+
* | Wait for async resource | Truthy |
|
|
99
|
+
* | Check boolean state (true or false) | Explicit |
|
|
100
|
+
* | Allow values such `0` or `""` | Explicit |
|
|
101
|
+
* | Distinguish `null` or `undefined` | Explicit |
|
|
102
|
+
* | Implement exact application logic | Explicit |
|
|
103
|
+
*
|
|
104
|
+
* <details>
|
|
105
|
+
* <summary>Read More</summary>
|
|
106
|
+
*
|
|
107
|
+
* > [!WARNING]
|
|
108
|
+
* >
|
|
109
|
+
* > `when()` and `whenOnce()` functions only trigger the callback when the expression changes and then the value satisfies the expression,
|
|
110
|
+
* > such as *false -> true -> false*, but not *true -> true*.
|
|
111
|
+
* >
|
|
112
|
+
* > Be careful with initial and default property values. For example, if you are watching for a property that is `true` by default,
|
|
113
|
+
* > such as [FeatureLayer.visible](https://developers.arcgis.com/javascript/latest/references/core/layers/FeatureLayer/), using a truthy check will not trigger the callback
|
|
114
|
+
* > until the property becomes `false` and then `true` again, which may not be the intended behavior.
|
|
115
|
+
*
|
|
116
|
+
* The snippets below use the Popup component's [open](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-popup/#open) property in the `getValue` expression.
|
|
117
|
+
* The first snippet uses a truthy check to determine when the popup is open,
|
|
118
|
+
* which is useful when you want to run the callback whenever the popup becomes visible.
|
|
119
|
+
* The property is `false` by default, so the callback will run when the popup opens,
|
|
120
|
+
* but not on subsequent changes that keep it open. Once the popup is closed, the callback will run again when it opens.
|
|
121
|
+
*
|
|
122
|
+
* ```js
|
|
123
|
+
* const viewElement = document.querySelector("arcgis-map");
|
|
124
|
+
*
|
|
125
|
+
* const handle = reactiveUtils.when(() => viewElement.popupElement.open, () => {
|
|
126
|
+
* console.log("Truthy check for popup open");
|
|
127
|
+
* });
|
|
128
|
+
*
|
|
129
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
130
|
+
* handle.remove();
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* Other truthy examples include:
|
|
134
|
+
* ```js
|
|
135
|
+
* () => viewElement.ready
|
|
136
|
+
* () => layer.loaded
|
|
137
|
+
* () => layer.visible
|
|
138
|
+
* ```
|
|
139
|
+
*
|
|
140
|
+
* Use explicit value checks when your logic depends on a specific value,
|
|
141
|
+
* rather than simply whether a value is truthy.
|
|
142
|
+
*
|
|
143
|
+
* This is useful when valid values may be falsy, such as `0`, `""`, or
|
|
144
|
+
* `false`, and a truthy check would produce unintended results.
|
|
145
|
+
*
|
|
146
|
+
* For example, to react only when the map is at a specific scale:
|
|
147
|
+
*
|
|
148
|
+
* ```js
|
|
149
|
+
* const handle = reactiveUtils.when(() => viewElement.scale === 5000, () => {
|
|
150
|
+
* console.log("The map is at scale 1:5000");
|
|
151
|
+
* });
|
|
152
|
+
*
|
|
153
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
154
|
+
* handle.remove();
|
|
155
|
+
* ```
|
|
156
|
+
*
|
|
157
|
+
* Other examples include:
|
|
158
|
+
*
|
|
159
|
+
* ```js
|
|
160
|
+
* () => viewElement.updating === false
|
|
161
|
+
* () => layer.visible === false
|
|
37
162
|
* ```
|
|
38
163
|
*
|
|
164
|
+
* See the MDN documentation to learn more about
|
|
165
|
+
* [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) and
|
|
166
|
+
* [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) values.
|
|
167
|
+
*
|
|
168
|
+
* </details>
|
|
169
|
+
*
|
|
170
|
+
* <span id="async-vs-sync"></span>
|
|
171
|
+
* ### Async versus sync callbacks
|
|
172
|
+
*
|
|
173
|
+
* Understanding the difference between asynchronous and synchronous callbacks is essential when working with `reactiveUtils`.
|
|
174
|
+
* The timing of when your callback executes, either immediately or on the next microtask,
|
|
175
|
+
* can impact both application behavior and performance.
|
|
176
|
+
*
|
|
177
|
+
* <details>
|
|
178
|
+
* <summary>Read More</summary>
|
|
179
|
+
*
|
|
180
|
+
* By default, [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch), [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) and [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on)
|
|
181
|
+
* functions are asynchronous, meaning that the callback will run on the next [microtask](https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API/Microtask_guide) after the
|
|
182
|
+
* expression value changes. This allows for batching of multiple changes and can help with
|
|
183
|
+
* performance. However, if you need the callback to run synchronously with the change, you
|
|
184
|
+
* can set the `sync` option to `true` in the options parameter.
|
|
185
|
+
*
|
|
186
|
+
* [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) resolve via a Promise,
|
|
187
|
+
* so they are always asynchronous and cannot be made synchronous. If the condition is
|
|
188
|
+
* already satisfied when `once()` or `whenOnce()` is called, the promise will resolve
|
|
189
|
+
* on the next microtask with the current value.
|
|
190
|
+
*
|
|
191
|
+
* One nuance, if you provide `initial: true` in the [ReactiveWatchOptions](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#ReactiveWatchOptions)
|
|
192
|
+
* for `watch()` and `when()`, the callback will run immediately after initialization if the
|
|
193
|
+
* condition is met, and then continue to watch for changes. In this case, the callback runs
|
|
194
|
+
* synchronously with the initial check, but subsequent calls are asynchronous.
|
|
195
|
+
* This is useful when you don’t want to duplicate initialization logic or manually “seed” state.
|
|
196
|
+
*
|
|
197
|
+
* ```js
|
|
198
|
+
* const handle = reactiveUtils.when(
|
|
199
|
+
* () => layer.visible === true,
|
|
200
|
+
* () => showLayerUI(),
|
|
201
|
+
* { initial: true }
|
|
202
|
+
* );
|
|
203
|
+
*
|
|
204
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
205
|
+
* handle.remove();
|
|
206
|
+
* ```
|
|
207
|
+
*
|
|
208
|
+
* Without `initial: true`, you might miss the fact that `layer.visible` was already true at startup and only respond to future changes.
|
|
209
|
+
*
|
|
210
|
+
* </details>
|
|
211
|
+
*
|
|
39
212
|
* <span id="working-with-collections"></span>
|
|
40
213
|
* ### Working with collections
|
|
41
214
|
*
|
|
42
|
-
* `reactiveUtils` can
|
|
43
|
-
*
|
|
44
|
-
*
|
|
215
|
+
* `reactiveUtils` can observe changes with a [Collection](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/), such as the Map component’s
|
|
216
|
+
* [allLayerViews](https://developers.arcgis.com/javascript/latest/references/map-components/components/arcgis-map/#allLayerViews).
|
|
217
|
+
* Methods like [Collection.map()](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/#map) and [Collection.filter()](https://developers.arcgis.com/javascript/latest/references/core/core/Collection/#filter),
|
|
218
|
+
* can be used in the `getValue` expression to derive values.
|
|
219
|
+
* This ensures the callback reacts to additions, removals, or updates in the collection.
|
|
45
220
|
*
|
|
46
221
|
* ```js
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* () => viewElement.map.allLayers.map( layer => layer.id),
|
|
52
|
-
* (ids) => {
|
|
53
|
-
* console.log(`FeatureLayer IDs ${ids}`);
|
|
222
|
+
* const handle = reactiveUtils.watch(
|
|
223
|
+
* () => viewElement.allLayerViews.map((layerView) => layerView.visible),
|
|
224
|
+
* (layerViews) => {
|
|
225
|
+
* console.log(`Visible layerViews: ${layerViews}`);
|
|
54
226
|
* });
|
|
227
|
+
*
|
|
228
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
229
|
+
* handle.remove();
|
|
55
230
|
* ```
|
|
56
231
|
*
|
|
57
232
|
* <span id="working-with-objects"></span>
|
|
58
233
|
* ### Working with objects
|
|
59
234
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
235
|
+
* `reactiveUtils` allows you to track object properties using dot notation
|
|
236
|
+
* (e.g. `viewElement.updating`) or bracket notation (e.g. `viewElement["updating"]`).
|
|
237
|
+
*
|
|
238
|
+
* Optional chaining (`?.`) can be used to safely access nested properties
|
|
239
|
+
* without manually checking each level.
|
|
65
240
|
*
|
|
66
241
|
* ```js
|
|
67
|
-
*
|
|
68
|
-
* // whenever the map's extent changes
|
|
69
|
-
* const viewElement = document.querySelector("arcgis-map");
|
|
70
|
-
* reactiveUtils.watch(
|
|
242
|
+
* const handle = reactiveUtils.watch(
|
|
71
243
|
* () => viewElement?.extent?.xmin,
|
|
72
244
|
* (xmin) => {
|
|
73
|
-
* console.log(`Extent change xmin = ${xmin}`)
|
|
74
|
-
* }
|
|
245
|
+
* console.log(`Extent change xmin = ${xmin}`);
|
|
246
|
+
* }
|
|
247
|
+
* );
|
|
248
|
+
*
|
|
249
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
250
|
+
* handle.remove();
|
|
75
251
|
* ```
|
|
76
252
|
*
|
|
77
|
-
* <span id="
|
|
78
|
-
* ###
|
|
253
|
+
* <span id="resourcehandles-and-promises"></span>
|
|
254
|
+
* ### ResourceHandles and Promises
|
|
79
255
|
*
|
|
80
256
|
* The [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch), [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on) and
|
|
81
|
-
* [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when)
|
|
257
|
+
* [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) functions return a [ResourceHandle](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/#ResourceHandle).
|
|
258
|
+
* Handles retain references to observed objects and callbacks until they are removed.
|
|
259
|
+
* The [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) functions return a
|
|
260
|
+
* Promise instead of a `ResourceHandle` and have the option to be cancelled via an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal). When cancelled, the Promise settles and is eligible for disposal.
|
|
261
|
+
*
|
|
262
|
+
* [watch()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#watch) and [when()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#when) have an optional `once` property in
|
|
263
|
+
* their `options` parameter. When `once: true` is set, the returned `ResourceHandle` will automatically remove
|
|
264
|
+
* itself after the first time the callback is executed, which can be useful for one-time conditions
|
|
265
|
+
* while still allowing for manual removal if needed.
|
|
266
|
+
*
|
|
267
|
+
* <details>
|
|
268
|
+
* <summary>Read More</summary>
|
|
269
|
+
*
|
|
270
|
+
* To avoid memory leaks:
|
|
271
|
+
* * Remove handles when the reference is no longer needed, such as during component teardown or before creating a replacement handle.
|
|
272
|
+
* * Use [Handles](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/) to manage groups of handles.
|
|
273
|
+
* * Abort unresolved async operations, this allows them to be disposed.
|
|
274
|
+
*
|
|
275
|
+
* Removing a handle stops the observation and releases references to observed objects and callbacks,
|
|
276
|
+
* allowing them to be garbage collected.
|
|
277
|
+
* Handle removal is idempotent and can be safely called multiple times.
|
|
82
278
|
*
|
|
83
279
|
* ```js
|
|
84
|
-
* //
|
|
85
|
-
* const viewElement = document.querySelector("arcgis-map");
|
|
280
|
+
* // Remove a ResourceHandle to stop watching for changes
|
|
86
281
|
* const handle = reactiveUtils.watch(
|
|
87
282
|
* () => viewElement?.extent?.xmin,
|
|
88
283
|
* (xmin) => {
|
|
89
284
|
* console.log(`Extent change xmin = ${xmin}`)
|
|
90
285
|
* });
|
|
91
286
|
*
|
|
92
|
-
* //
|
|
287
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
93
288
|
* handle.remove()
|
|
94
289
|
* ```
|
|
95
290
|
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* methods also offer the option to cancel the async callback via an
|
|
99
|
-
* [`AbortSignal`](https://developer.mozilla.org/docs/Web/API/AbortController/signal).
|
|
100
|
-
* Be aware that if the returned Promise is not resolved, it can also result in a memory leak.
|
|
291
|
+
* Use [Handles](https://developers.arcgis.com/javascript/latest/references/core/core/Handles/) to group multiple ResourceHandles and remove them together, such as when a component is torn down.
|
|
292
|
+
* This also makes it easier to manage handles by name.
|
|
101
293
|
*
|
|
102
294
|
* ```js
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
295
|
+
* const handles = new Handles();
|
|
296
|
+
* handles.add(
|
|
297
|
+
* reactiveUtils.watch(...),
|
|
298
|
+
* "view-watcher" // groupKey is optional but can be helpful for managing handles
|
|
299
|
+
* );
|
|
106
300
|
*
|
|
107
|
-
* //
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* .then((animation) => {
|
|
111
|
-
* console.log(`View animation state is ${animation.state}`)
|
|
112
|
-
* });
|
|
301
|
+
* // In another function or during component teardown
|
|
302
|
+
* handles.remove("view-watcher");
|
|
303
|
+
* ```
|
|
113
304
|
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
305
|
+
* The [once()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#once) and [whenOnce()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#whenOnce) functions return a Promise.
|
|
306
|
+
* In some advanced use cases where an action may take additional time, these
|
|
307
|
+
* functions also offer the option to cancel the async callback via an [`AbortSignal`](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
|
|
308
|
+
*
|
|
309
|
+
* > [!WARNING]
|
|
310
|
+
* >
|
|
311
|
+
* > If the component being watched is removed before the promise resolves,
|
|
312
|
+
* > it can lead to memory leaks or unhandled promise rejections.
|
|
313
|
+
*
|
|
314
|
+
* ```js
|
|
315
|
+
* let abortController = new AbortController();
|
|
316
|
+
* const { signal } = abortController;
|
|
317
|
+
*
|
|
318
|
+
* // Cancel the async callback by sending an AbortSignal
|
|
319
|
+
* const abort = () => {
|
|
320
|
+
* abortController?.abort();
|
|
117
321
|
* }
|
|
322
|
+
*
|
|
323
|
+
* // Set the signal property to watch for abort signals
|
|
324
|
+
* // and reject the promise if the signal is aborted before the promise resolves
|
|
325
|
+
* reactiveUtils.whenOnce(
|
|
326
|
+
* () => !viewElement.updating,
|
|
327
|
+
* { signal }
|
|
328
|
+
* )
|
|
329
|
+
* .then((updating) => {
|
|
330
|
+
* console.log("Map is not updating", updating);
|
|
331
|
+
* })
|
|
332
|
+
* .catch((error) => {
|
|
333
|
+
* if (error.name === "AbortError") {
|
|
334
|
+
* console.log("The async callback was aborted");
|
|
335
|
+
* } else {
|
|
336
|
+
* console.error("An unexpected error occurred:", error);
|
|
337
|
+
* }
|
|
338
|
+
* })
|
|
339
|
+
* .finally(() => {
|
|
340
|
+
* console.log("Async callback has completed or was aborted");
|
|
341
|
+
* abortController = null;
|
|
342
|
+
* });
|
|
118
343
|
* ```
|
|
119
344
|
*
|
|
120
|
-
*
|
|
121
|
-
* ### Working with truthy values
|
|
345
|
+
* See the SDK guide topic on [Async cancellation with AbortController](https://developers.arcgis.com/javascript/latest/async-cancellation-with-abortcontroller/) for more details and examples.
|
|
122
346
|
*
|
|
123
|
-
*
|
|
124
|
-
* in boolean contexts. To learn more about using truthy, visit this
|
|
125
|
-
* [MDN Web doc](https://developer.mozilla.org/docs/Glossary/Truthy) article. The snippets below use the [Popup.visible](https://developers.arcgis.com/javascript/latest/references/core/widgets/Popup/) property, which is a boolean.
|
|
347
|
+
* </details>
|
|
126
348
|
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* reactiveUtils
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
349
|
+
* <span id="typescript"></span>
|
|
350
|
+
* ### Working with TypeScript
|
|
351
|
+
*
|
|
352
|
+
* `reactiveUtils` also works with TypeScript. TypeScript infers the expression result type from the `getValue`
|
|
353
|
+
* expression and passes it to the callback.
|
|
354
|
+
* For array expressions, use explicit tuple typing when positional meaning matters.
|
|
355
|
+
* Using `as const` preserves tuple types so callback parameters are strongly typed by position.
|
|
356
|
+
* You can also use objects to group values and maintain strong typing without relying on position.
|
|
357
|
+
*
|
|
358
|
+
* <details>
|
|
359
|
+
* <summary>Read More</summary>
|
|
360
|
+
*
|
|
361
|
+
* The first snippet shows how to use `as const` for tuple typing when tracking multiple properties in an array.
|
|
362
|
+
*
|
|
363
|
+
* ```ts
|
|
364
|
+
* import { watch } from "@arcgis/core/core/reactiveUtils.js";
|
|
365
|
+
* import type { ArcgisMap } from "@arcgis/map-components/components/arcgis-map";
|
|
366
|
+
*
|
|
367
|
+
* // Get a reference to the map component
|
|
368
|
+
* const arcgisMap = document.querySelector<ArcgisMap>("arcgis-map");
|
|
369
|
+
*
|
|
370
|
+
* const handle = reactiveUtils.watch(
|
|
371
|
+
* () => [view.stationary, view.zoom] as const,
|
|
372
|
+
* ([stationary, zoom], oldValue) => {
|
|
373
|
+
* if (stationary) {
|
|
374
|
+
* const previousZoom = oldValue?.[1];
|
|
375
|
+
* console.log("Zoom:", zoom, "Previous:", previousZoom);
|
|
376
|
+
* }
|
|
377
|
+
* }
|
|
378
|
+
* );
|
|
379
|
+
*
|
|
380
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
381
|
+
* handle.remove();
|
|
135
382
|
* ```
|
|
136
383
|
*
|
|
384
|
+
* The second snippet shows how to use an object to group values and maintain strong typing without
|
|
385
|
+
* relying on position. One advantage of this approach is the callback properties are named.
|
|
386
|
+
* The order of properties in the `getValue` expression doesn't matter. This improves maintainability
|
|
387
|
+
* and readability, especially when tracking multiple properties or when the expression is complex
|
|
388
|
+
* because the properties are matched by the name and not position.
|
|
389
|
+
*
|
|
390
|
+
* ```ts
|
|
391
|
+
* const handle = reactiveUtils.watch(
|
|
392
|
+
* () => ({
|
|
393
|
+
* scale: viewElement.scale,
|
|
394
|
+
* stationary: viewElement.stationary,
|
|
395
|
+
* extent: viewElement.extent
|
|
396
|
+
* }),
|
|
397
|
+
* ({ stationary, extent, scale }) => {
|
|
398
|
+
* if (stationary) {
|
|
399
|
+
* console.log("View stopped moving");
|
|
400
|
+
* console.log("Scale:", scale);
|
|
401
|
+
* console.log("Extent:", extent);
|
|
402
|
+
* }
|
|
403
|
+
* }
|
|
404
|
+
* );
|
|
405
|
+
* ```
|
|
406
|
+
*
|
|
407
|
+
* If the `getValue` expression may return `null` or `undefined`,
|
|
408
|
+
* shape the expression so the callback only runs when a defined value is available.
|
|
409
|
+
*
|
|
410
|
+
* This avoids unnecessary callback executions and ensures TypeScript receives a
|
|
411
|
+
* narrowed type.
|
|
412
|
+
*
|
|
413
|
+
* ```ts
|
|
414
|
+
* const handle = reactiveUtils.when(
|
|
415
|
+
* () => viewElement.popupElement?.selectedFeature?.geometry,
|
|
416
|
+
* (geometry) => {
|
|
417
|
+
* console.log(geometry.type);
|
|
418
|
+
* }
|
|
419
|
+
* );
|
|
420
|
+
*
|
|
421
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
422
|
+
* handle.remove();
|
|
423
|
+
* ```
|
|
424
|
+
*
|
|
425
|
+
* </details>
|
|
426
|
+
*
|
|
137
427
|
* @since 4.23
|
|
138
428
|
* @see [Watch for changes guide topic](https://developers.arcgis.com/javascript/latest/watch-for-changes/)
|
|
139
429
|
* @see [Sample - Watch for changes in components using reactiveUtils](https://developers.arcgis.com/javascript/latest/sample-code/watch-for-changes-reactiveutils-components/)
|
|
@@ -156,7 +446,7 @@ export interface ReactiveWatchOptions<T = unknown> {
|
|
|
156
446
|
*/
|
|
157
447
|
readonly initial?: boolean;
|
|
158
448
|
/**
|
|
159
|
-
* Whether to fire the callback synchronously or on the next
|
|
449
|
+
* Whether to fire the callback synchronously or on the next microtask.
|
|
160
450
|
*
|
|
161
451
|
* @default false
|
|
162
452
|
*/
|
|
@@ -182,14 +472,14 @@ export interface ReactiveWatchOptions<T = unknown> {
|
|
|
182
472
|
export type ReactiveEqualityFunction<T> = (newValue: T, oldValue: T) => boolean;
|
|
183
473
|
|
|
184
474
|
/**
|
|
185
|
-
*
|
|
475
|
+
* Expression which is auto-tracked and should return a value to pass to the [ReactiveWatchCallback](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#ReactiveWatchCallback).
|
|
186
476
|
*
|
|
187
477
|
* @returns The new value.
|
|
188
478
|
*/
|
|
189
479
|
export type ReactiveWatchExpression<T> = () => T;
|
|
190
480
|
|
|
191
481
|
/**
|
|
192
|
-
*
|
|
482
|
+
* Expression which is auto-tracked and should return an event target to which
|
|
193
483
|
* an event listener is to be added.
|
|
194
484
|
*
|
|
195
485
|
* @returns The event target.
|
|
@@ -205,14 +495,14 @@ export type ReactiveOnExpression<T> = () => T;
|
|
|
205
495
|
export type ReactiveWatchCallback<T> = (newValue: T, oldValue?: T) => void;
|
|
206
496
|
|
|
207
497
|
/**
|
|
208
|
-
* Function
|
|
498
|
+
* Function to be called when an event is emitted or dispatched.
|
|
209
499
|
*
|
|
210
500
|
* @param event - The event emitted by the target.
|
|
211
501
|
*/
|
|
212
502
|
export type ReactiveOnCallback<T> = (event: T) => void;
|
|
213
503
|
|
|
214
504
|
/**
|
|
215
|
-
* Tracks any properties accessed in the `getValue`
|
|
505
|
+
* Tracks any properties accessed in the `getValue` expression and calls the `callback`
|
|
216
506
|
* when any of them change.
|
|
217
507
|
*
|
|
218
508
|
* @param getValue - Function used to get the current value. All accessed properties will be tracked.
|
|
@@ -221,28 +511,30 @@ export type ReactiveOnCallback<T> = (event: T) => void;
|
|
|
221
511
|
* @returns A watch handle.
|
|
222
512
|
* @example
|
|
223
513
|
* // Watching for changes in a boolean value
|
|
224
|
-
* // Equivalent to watchUtils.watch()
|
|
225
514
|
* const viewElement = document.querySelector("arcgis-map");
|
|
226
|
-
* reactiveUtils.watch(
|
|
227
|
-
* () => viewElement.
|
|
515
|
+
* const handle = reactiveUtils.watch(
|
|
516
|
+
* () => viewElement.popupElement.open,
|
|
228
517
|
* () => {
|
|
229
|
-
* console.log(`Popup
|
|
518
|
+
* console.log(`Popup open: ${viewElement.popupElement.open}`);
|
|
230
519
|
* });
|
|
520
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
521
|
+
* handle.remove();
|
|
231
522
|
* @example
|
|
232
523
|
* // Watching for changes within a Collection
|
|
233
524
|
* const viewElement = document.querySelector("arcgis-map");
|
|
234
|
-
* reactiveUtils.watch(
|
|
525
|
+
* const handle = reactiveUtils.watch(
|
|
235
526
|
* () => viewElement.map.allLayers.length,
|
|
236
527
|
* () => {
|
|
237
528
|
* console.log(`Layer collection length changed: ${viewElement.map.allLayers.length}`);
|
|
238
529
|
* });
|
|
530
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
531
|
+
* handle.remove();
|
|
239
532
|
* @example
|
|
240
533
|
* // Watch for changes in a numerical value.
|
|
241
534
|
* // Providing `initial: true` in ReactiveWatchOptions
|
|
242
535
|
* // checks immediately after initialization
|
|
243
|
-
* // Equivalent to watchUtils.init()
|
|
244
536
|
* const viewElement = document.querySelector("arcgis-map");
|
|
245
|
-
* reactiveUtils.watch(
|
|
537
|
+
* const handle = reactiveUtils.watch(
|
|
246
538
|
* () => viewElement.zoom,
|
|
247
539
|
* () => {
|
|
248
540
|
* console.log(`zoom changed to ${viewElement.zoom}`);
|
|
@@ -250,6 +542,8 @@ export type ReactiveOnCallback<T> = (event: T) => void;
|
|
|
250
542
|
* {
|
|
251
543
|
* initial: true
|
|
252
544
|
* });
|
|
545
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
546
|
+
* handle.remove();
|
|
253
547
|
* @example
|
|
254
548
|
* // Watch properties from multiple sources
|
|
255
549
|
* const viewElement = document.querySelector("arcgis-map");
|
|
@@ -262,48 +556,53 @@ export type ReactiveOnCallback<T> = (event: T) => void;
|
|
|
262
556
|
* }
|
|
263
557
|
* }
|
|
264
558
|
* );
|
|
559
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
560
|
+
* handle.remove();
|
|
265
561
|
*/
|
|
266
562
|
export function watch<T, U extends T>(getValue: ReactiveWatchExpression<T>, callback: ReactiveWatchCallback<T>, options?: ReactiveWatchOptions<U>): ResourceHandle;
|
|
267
563
|
|
|
268
564
|
/**
|
|
269
|
-
* Watches the value returned by the `getValue`
|
|
565
|
+
* Watches the value returned by the `getValue` expression and calls the `callback` when it becomes truthy.
|
|
270
566
|
*
|
|
271
|
-
* @param getValue -
|
|
567
|
+
* @param getValue - Expression used to get the current value. All accessed properties will be tracked.
|
|
272
568
|
* @param callback - The function to call when the value becomes truthy.
|
|
273
569
|
* @param options - Options used to configure how the tracking happens and how the callback is to be called.
|
|
274
570
|
* @returns A watch handle.
|
|
275
571
|
* @example
|
|
276
572
|
* // Observe when a boolean property becomes not truthy
|
|
277
|
-
*
|
|
278
|
-
* reactiveUtils.when(
|
|
573
|
+
* const handle = reactiveUtils.when(
|
|
279
574
|
* () => !layerView.updating,
|
|
280
575
|
* () => {
|
|
281
576
|
* console.log("LayerView finished updating.");
|
|
282
577
|
* });
|
|
578
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
579
|
+
* handle.remove();
|
|
283
580
|
* @example
|
|
284
581
|
* // Observe when a boolean property becomes true
|
|
285
|
-
* // Equivalent to watchUtils.whenTrue()
|
|
286
582
|
* const viewElement = document.querySelector("arcgis-map");
|
|
287
|
-
* reactiveUtils.when(
|
|
583
|
+
* const handle = reactiveUtils.when(
|
|
288
584
|
* () => viewElement?.stationary === true,
|
|
289
585
|
* async () => {
|
|
290
586
|
* console.log("User is no longer interacting with the map");
|
|
291
587
|
* await drawBuffer();
|
|
292
588
|
* });
|
|
589
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
590
|
+
* handle.remove();
|
|
293
591
|
* @example
|
|
294
592
|
* // Observe a boolean property for truthiness.
|
|
295
593
|
* // Providing `once: true` in ReactiveWatchOptions
|
|
296
594
|
* // only fires the callback once
|
|
297
|
-
* // Equivalent to watchUtils.whenFalseOnce()
|
|
298
595
|
* const featuresComponent = document.querySelector("arcgis-features");
|
|
299
|
-
* reactiveUtils.when(
|
|
300
|
-
* () =>
|
|
596
|
+
* const handle = reactiveUtils.when(
|
|
597
|
+
* () => featuresComponent.open,
|
|
301
598
|
* () => {
|
|
302
|
-
* console.log(
|
|
599
|
+
* console.log("The features component is open");
|
|
303
600
|
* },
|
|
304
601
|
* {
|
|
305
602
|
* once: true
|
|
306
603
|
* });
|
|
604
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
605
|
+
* handle.remove();
|
|
307
606
|
*/
|
|
308
607
|
export function when<T, U extends T>(getValue: ReactiveWatchExpression<T | null | undefined>, callback: (newValue: T, oldValue?: T) => void, options?: ReactiveWatchOptions<U>): ResourceHandle;
|
|
309
608
|
|
|
@@ -317,7 +616,7 @@ export type ReactiveListenerChangeCallback<T> = (target: T) => void;
|
|
|
317
616
|
/** Options used to configure the behavior of [on()](https://developers.arcgis.com/javascript/latest/references/core/core/reactiveUtils/#on). */
|
|
318
617
|
export interface ReactiveOnOptions<Target> {
|
|
319
618
|
/**
|
|
320
|
-
* Whether to fire the callback synchronously or on the next
|
|
619
|
+
* Whether to fire the callback synchronously or on the next microtask.
|
|
321
620
|
*
|
|
322
621
|
* @default false
|
|
323
622
|
*/
|
|
@@ -347,19 +646,21 @@ export interface ReactiveOnOptions<Target> {
|
|
|
347
646
|
* @example
|
|
348
647
|
* // Adds a click event on a map component when it changes
|
|
349
648
|
* const viewElement = document.querySelector("arcgis-map");
|
|
350
|
-
* reactiveUtils.on(
|
|
649
|
+
* const handle = reactiveUtils.on(
|
|
351
650
|
* () => viewElement,
|
|
352
651
|
* "arcgisViewClick",
|
|
353
652
|
* (event) => {
|
|
354
653
|
* console.log("arcgisViewClick event emitted: ", event);
|
|
355
654
|
* });
|
|
655
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
656
|
+
* handle.remove();
|
|
356
657
|
* @example
|
|
357
658
|
* // Adds a drag event on a map component and adds a callback
|
|
358
659
|
* // to check when the listener is added and removed.
|
|
359
660
|
* // Providing `once: true` in the ReactiveListenerOptions
|
|
360
661
|
* // removes the event after first callback.
|
|
361
662
|
* const viewElement = document.querySelector("arcgis-map");
|
|
362
|
-
* reactiveUtils.on(
|
|
663
|
+
* const handle = reactiveUtils.on(
|
|
363
664
|
* () => viewElement,
|
|
364
665
|
* "arcgisViewDrag",
|
|
365
666
|
* (event) => {
|
|
@@ -370,11 +671,13 @@ export interface ReactiveOnOptions<Target> {
|
|
|
370
671
|
* onListenerAdd: () => console.log("Drag listener added!"),
|
|
371
672
|
* onListenerRemove: () => console.log("Drag listener removed!")
|
|
372
673
|
* });
|
|
674
|
+
* // Remove the handle when it's no longer needed to stop watching for changes
|
|
675
|
+
* handle.remove();
|
|
373
676
|
*/
|
|
374
677
|
export function on<Target extends EventTarget | EventedMixin>(getTarget: ReactiveOnExpression<Target | null | undefined>, eventName: string, callback: ReactiveOnCallback<any>, options?: ReactiveOnOptions<Target>): ResourceHandle;
|
|
375
678
|
|
|
376
679
|
/**
|
|
377
|
-
* Tracks any properties being evaluated by the `getValue`
|
|
680
|
+
* Tracks any properties being evaluated by the `getValue` expression. When `getValue` changes, it
|
|
378
681
|
* returns a promise containing the value. This method only tracks a single change.
|
|
379
682
|
*
|
|
380
683
|
* @param getValue - Expression to be tracked.
|
|
@@ -382,15 +685,14 @@ export function on<Target extends EventTarget | EventedMixin>(getTarget: Reactiv
|
|
|
382
685
|
* @returns A promise which resolves when the tracked expression changes.
|
|
383
686
|
* @example
|
|
384
687
|
* // Observe the first time a property equals a specific string value
|
|
385
|
-
* // Equivalent to watchUtils.once()
|
|
386
688
|
* reactiveUtils.once(
|
|
387
689
|
* () => featureLayer.loadStatus === "loaded")
|
|
388
690
|
* .then(() => {
|
|
389
691
|
* console.log("featureLayer loadStatus is loaded.");
|
|
390
692
|
* });
|
|
391
693
|
* @example
|
|
392
|
-
* // Use a comparison operator to
|
|
393
|
-
* //
|
|
694
|
+
* // Use a comparison operator to resolve on the first tracked change that
|
|
695
|
+
* // matches this expression.
|
|
394
696
|
* const viewElement = document.querySelector("arcgis-map");
|
|
395
697
|
* const someFunction = async () => {
|
|
396
698
|
* await reactiveUtils.once(() => viewElement.zoom > 20);
|
|
@@ -408,7 +710,7 @@ export function on<Target extends EventTarget | EventedMixin>(getTarget: Reactiv
|
|
|
408
710
|
export function once<T>(getValue: ReactiveWatchExpression<T>, signal?: AbortSignal | AbortOptions | null | undefined): Promise<T>;
|
|
409
711
|
|
|
410
712
|
/**
|
|
411
|
-
* Tracks any properties being evaluated by the `getValue`
|
|
713
|
+
* Tracks any properties being evaluated by the `getValue` expression. When `getValue` becomes truthy,
|
|
412
714
|
* it returns a promise containing the value. This method only tracks a single change.
|
|
413
715
|
*
|
|
414
716
|
* @param getValue - Expression to be tracked.
|
|
@@ -416,31 +718,30 @@ export function once<T>(getValue: ReactiveWatchExpression<T>, signal?: AbortSign
|
|
|
416
718
|
* @returns A promise which resolves once the tracked expression becomes truthy.
|
|
417
719
|
* @example
|
|
418
720
|
* // Check for the first time a property becomes truthy
|
|
419
|
-
* // Equivalent to watchUtils.whenOnce()
|
|
420
721
|
* const viewElement = document.querySelector("arcgis-map");
|
|
421
722
|
* reactiveUtils.whenOnce(
|
|
422
|
-
* () => viewElement.
|
|
723
|
+
* () => viewElement.popupElement.open)
|
|
423
724
|
* .then(() => {
|
|
424
725
|
* console.log("Popup used for the first time");
|
|
425
726
|
* });
|
|
426
727
|
* @example
|
|
427
728
|
* // Check for the first time a property becomes not truthy
|
|
428
|
-
* // Equivalent to watchUtils.whenFalseOnce()
|
|
429
729
|
* const someFunction = async () => {
|
|
430
730
|
* await reactiveUtils.whenOnce(() => !layerView.updating);
|
|
431
731
|
* console.log("LayerView is no longer updating");
|
|
432
732
|
* }
|
|
433
733
|
* @example
|
|
434
734
|
* // Check for the first time a property becomes truthy
|
|
435
|
-
* // And, use AbortController to
|
|
735
|
+
* // And, use AbortController to cancel the async callback
|
|
436
736
|
* const abortController = new AbortController();
|
|
437
737
|
* const viewElement = document.querySelector("arcgis-map");
|
|
438
738
|
*
|
|
439
739
|
* // Observe the map component's updating state
|
|
740
|
+
* // The updating property is false by default
|
|
440
741
|
* reactiveUtils.whenOnce(
|
|
441
742
|
* () => viewElement?.updating, {signal: abortController.signal})
|
|
442
743
|
* .then((updating) => {
|
|
443
|
-
* console.log(`Map component
|
|
744
|
+
* console.log(`Map component updated.`)
|
|
444
745
|
* });
|
|
445
746
|
*
|
|
446
747
|
* // Cancel the async callback
|