In previous releases of ArcGIS Experience Builder, as a custom widget developer, you would access the underlying map view using the JimuMapView.view property. With the migration to the ArcGIS Maps SDK for JavaScript web components, the new pattern for accessing map views in Experience Builder is to use JimuMapView.mapComponent, which is supported by arcgis-map or arcgis-scene, instead of relying on the newly deprecated JimuMapView.view. This topic describes the recommended patterns for selecting and consuming map views, layers, and tables in your custom widget.

What has changed

The ArcGIS Maps SDK for JavaScript has deprecated the widget construction model for many map UI scenarios. Experience Builder now aligns with the component API model:

  • Previous pattern: new MapView() and new SceneView().
  • Current pattern: arcgis-map and arcgis-scene, exposed through Experience Builder map abstractions such as JimuMapView.

For most Experience Builder widgets, this means:

  • Do not create map or scene views directly.
  • Select and consume the active JimuMapView that is created and managed by the Map widget.
  • Use ArcGIS map components and set referenceElement to the map component element from JimuMapView.

Migration guidance

Use this mapping to migrate from the legacy pattern to the current Experience Builder pattern.

Legacy patternCurrent pattern
new MapView() / new SceneView() in widget codeUse MapWidgetSelector in settings and JimuMapViewComponent in runtime
Widget owns the map view lifecycleMap widget owns lifecycle; your widget consumes active JimuMapView
component.view = jimuMapView.viewcomponent.referenceElement = jimuMapView.mapComponent
jimuMapView.view.popup as primary popup entry pointjimuMapView.mapComponent.popupElement or jimuMapView.getPopupElement()

Widget settings and runtime patterns

The sections below describe the recommended new patterns for selecting and consuming map views, layers, and tables in your widget.

Select a map, layers, and tables in widget settings

To select a map, layers, and tables in your widget settings, use the following components:

  • Use MapWidgetSelector from jimu-ui/advanced/setting-components so users can choose a Map widget.

    • Use the onSelect callback to get selected map widget ID values.
    • Persist the selected ID list in widget config, usually via useMapWidgetIds.
    • Although this is stored as an array, many widgets use useMapWidgetIds?.[0] when one map widget is expected.
  • Use LayerSetting from jimu-ui/advanced/setting-components when the widget needs author-selected layers or tables.

    • LayerSetting can display both layers and tables.
    • If your widget needs tables, ensure table display is enabled in LayerSetting configuration.

Get the map, layers, and tables at runtime

  • To get access to the JimuMapView:

    • If you already have a jimuMapViewId, use MapViewManager.getInstance().getJimuMapViewById(jimuMapViewId).
    • The recommended pattern is to use JimuMapViewComponent with useMapWidgetId and the onActiveViewChange callback to get the active JimuMapView.
    • Always call await jimuMapView.whenJimuMapViewLoaded() before using the view.
  • To get access to the JimuLayerView:

    • Use jimuMapView.getAllLoadedJimuLayerViews() for already loaded layer views.
    • Use await jimuMapView.whenJimuLayerViewLoaded(jimuLayerViewId) for a specific layer view.
    • If you have a DataSource, use await jimuMapView.whenJimuLayerViewLoadedByDataSource(ds).
    • Use jimuMapView.addJimuLayerViewCreatedListener(listener) to handle layer views created later.
    • Remove listeners when no longer needed.

Layer-view loading pattern

As a developer, you want to retrieve layer views as soon as they are available for your custom widget. Here are the recommended patterns:

  • Avoid await jimuMapView.whenAllJimuLayerViewLoaded() unless you truly need every layer view. Waiting for all layer views can delay widget initialization.
  • In most cases, use getAllLoadedJimuLayerViews() along with addJimuLayerViewCreatedListener(listener).

Get the layer data source

When you want to retrieve the layer data source from a JimuLayerView:

  • Use jimuLayerView.layerDataSourceId for the bound layer data source ID.
  • Use jimuLayerView.getLayerDataSource() to access the layer data source.
  • If needed, call await jimuLayerView.createLayerDataSource().

Get the table data source

When you want to retrieve the JimuTable and its corresponding table data source:

  • Use jimuMapView.getJimuTables() for tables already created.
  • Use jimuMapView.addJimuTableCreatedListener(listener) for tables created later.
  • Use jimuMapView.removeJimuTableCreatedListener(listener) to clean up.
  • Use jimuTable.tableDataSourceId and jimuTable.getTableDataSource() for table data source access.
  • If needed, call await jimuTable.createTableDataSource().

Using the ArcGIS Maps SDK for JavaScript components

With the migration to the component API model, as a developer, you should use the ArcGIS Maps SDK components instead of the deprecated ArcGIS Maps SDK core widgets. For example, use arcgis-layer-list instead of the deprecated LayerList widget.

  • When you need to use ArcGIS map components, import loadArcGISMapComponents from jimu-core and call it to load the map component API.
  • Experience Builder now hosts map views through arcgis-map or arcgis-scene. It is recommended to:
    • Set component.referenceElement = jimuMapView.mapComponent. The jimuMapView.mapComponent property points to the underlying arcgis-map or arcgis-scene component.
    • Not rely on assigning component.view in your custom widget.
  • When you need to access the popup in your custom widget, it is recommended to use:
    • jimuMapView.mapComponent.popupElement or jimuMapView.getPopupElement().
    • Popup element events for popup state handling.
    • jimuMapView.mapComponent.openPopup() and jimuMapView.mapComponent.closePopup().

Code example

Access the underlying ArcGIS Maps SDK view.

This example shows a basic widget runtime example that gets the active JimuMapView and reads the view type.

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
24
25
26
27
28
29
30
31
import { React, type AllWidgetProps } from 'jimu-core'
import { JimuMapViewComponent, type JimuMapView } from 'jimu-arcgis'

export default function Widget (props: AllWidgetProps<any>) {
	const [jimuMapView, setJimuMapView] = React.useState<JimuMapView | null>(null)

	const onActiveViewChange = async (activeView: JimuMapView) => {
		if (!activeView) {
			setJimuMapView(null)
			return
		}

		await activeView.whenJimuMapViewLoaded()
		setJimuMapView(activeView)
	}

	return (
		<div className='widget-use-mapview-sceneview'>
			<JimuMapViewComponent
				useMapWidgetId={props.useMapWidgetIds?.[0]}
				onActiveViewChange={onActiveViewChange}
			/>

			{jimuMapView?.view && (
				<div>
					Active view type: {jimuMapView.view.type}
				</div>
			)}
		</div>
	)
}

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