Select to view content in your preferred language

Changing WebMap in Map widget programmatically

260
5
3 weeks ago
S3TmGIS
Emerging Contributor

Hi all,

I’m working in Experience Builder (Developer Edition) and I use two official widgets in my app:

  • Map widget – initially empty (no default web map configured)
  • Map Layers widget – connected to the Map widget

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!

 

 

0 Kudos
5 Replies
JeffreyThompson2
MVP Frequent Contributor

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?

GIS Developer
City of Arlington, Texas
0 Kudos
S3TmGIS
Emerging Contributor

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:

  • Deleting the old jimuMapView - broke the Map widget
  • Manipulating the global MapViewManager object and setting activeJimuMapView - didn’t work
  • Using the hidden switchMap function inside MapViewManager - didn’t work either (though it works fine when using the two web maps configured in the Map widget settings)

So, I’m stuck here. Any idea how to replace the old jimuMapView with a new one?

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

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.

GIS Developer
City of Arlington, Texas
0 Kudos
S3TmGIS
Emerging Contributor

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.

0 Kudos
JeffreyThompson2
MVP Frequent Contributor

You can use multiple Map Widgets. Place them inside a Section Widget and use Buttons or a View Navigation Widget to switch between them.

GIS Developer
City of Arlington, Texas
0 Kudos