Hi all,
I’m working in Experience Builder (Developer Edition) and I use two official widgets in my app:
At runtime, I programmatically swap the web map like this:
this.jimuMapView.view.map = webMap;
It works great, Map widget re-renders with the new web map, Map Layers widget shows the correct layers and most functionality works as expected.
The problem
In the Map Layers widget config, there’s an option Enable layer batch options (turn on/off all layers, expand/collapse all layers).
After swapping the web map programmatically: expand/collapse all layers works fine, but turn on/off all layers does nothing and opening the layer menu throws:
DataSource create error: TypeError: Cannot read properties of null (reading 'createDataSourceByLayer')
Despite the error, individual layer controls (turning single layers on/off, toggling visibility, etc.) still work. It’s only the batch toggle that fails.
It seems the batch toggle fails because the web map, when created and added programmatically, doesn’t have a corresponding DataSource registered in Experience Builder’s framework.
I attempted to create and register a new DataSource for the web map, and update appConfig:
const dsManager = DataSourceManager.getInstance();
const dsJson: DataSourceJson = {
id: `ds_webmap_${webMap.portalItem.id}`,
type: DataSourceTypes.WebMap,
portalUrl: webMap.portalItem.portal.url,
itemId: webMap.portalItem.id
};
const newDs = await dsManager.createDataSource(dsJson);
await (newDs as MapDataSource).childDataSourcesReady();
const appConfig = getAppStore().getState().appConfig;
let updatedConfig = appConfig.setIn(
['dataSources', dsJson.id],
dsJson
);
updatedConfig = updatedConfig.setIn(
['widgets', this.jimuMapView.mapWidgetId, 'useDataSources'],
[
{
dataSourceId: dsJson.id,
mainDataSourceId: dsJson.id
}
]
);
getAppStore().dispatch(appActions.appConfigChanged(updatedConfig));
But when I do this - the Map widget goes into endless loading and onActiveJimuMapViewChange is called with jimuMapView as null in widgets connected to the map.
Is there a way to programmatically change the Map widget’s web map and have the Map Layers widget (including “Enable layer batch options”) fully work?
Any tips, examples, or documentation links on the correct way to handle this would be greatly appreciated.
Thanks in advance!
I believe the createDataSource function is designed for creating a datasource from a layer. To get what you want, I think you will need to replace the entire jimuMapView. This example should be helpful.
https://github.com/Esri/arcgis-experience-builder-sdk-resources/tree/master/widgets/map-view
But more importantly, why? What are you trying to accomplish by loading a blank webmap then changing it to a different map?
Thanks for the reply.
The reason I need to do this is because I need to switch between multiple web maps at runtime, and the web maps I’m using are currently on a different portal, so I’m creating their objects programmatically.
Using MapViewManager to create a new jimuMapView inside MapViewManager looked promising - it successfully creates and registers a new view, similar to how two web maps behave when added via the Map widget settings. However, even though the layers display correctly in the Map widget, it breaks all the official Experience Builder widgets that interact with the map. I think they’re still listening to the old jimuMapView.
I also tried:
So, I’m stuck here. Any idea how to replace the old jimuMapView with a new one?
https://doc.arcgis.com/en/arcgis-online/administer/create-a-collaboration.htm
Can you share the webmaps through a distributed/partnered collaboration? Then you should be able to find them using the built-in interface.
In the future, the web maps will be on the same portal, but that doesn’t change my problem - I still need to switch between more than two maps at runtime. I also cannot use the webMap URL parameter, because they don’t want refresh application when switching web maps.
You can use multiple Map Widgets. Place them inside a Section Widget and use Buttons or a View Navigation Widget to switch between them.