How do you write code in a widget to replace an app's web map?
I attempted to use esri/arcgis/utils like this:
arcgisUtils.createMap(myWebMapId, this.map.id).then(lang.hitch(function(response) {
this.map = response.map;
}));
This code did not visibly change the map control. Then I had an idea to clear the contents of the map div before loading the map:
var mapDiv = dom.byId(this.map.id);
mapDiv.innerHTML = "";
arcgisUtils.createMap(myWebMapId, this.map.id).then(lang.hitch(function(response) {
this.map = response.map;
}));
In this case, the map control did load and display my web map! However, all of the app's widgets disappeared.
How can I replace the map contents without removing the app's widgets?
To avoid having to reset all the widget references manually what you could do instead is post an update to portal with your webmap json with additional layers using
var portal = portalUtils.getPortal(this.appConfig.portalUrl);
portal.getUser().then(lang.hitch(this, function (user) {
user.updateItem(this.map.itemId, argsUpdate).then(lang.hitch(this, function (updateItem) {
//if want to reload with what just pushed to portal
topic.publish('appConfigChanged', this.appConfig, 'mapChange'); //this will trigger map update which will refresh page and hence all the widgets
}));
}));
I have done something similar and sniffed out the structure of the json for webmap in fiddler. I then just update the json object with my changes.
If you want to make a brand new web map, I would suggest add an item and then update appConfig and call the change event
user.addItem(args, '').then(lang.hitch(this, function (newItem) {
if (newItem.success) {
var itemId = newItem.id;
this.appConfig.map.itemId = itemId;
topic.publish('appConfigChanged', this.appConfig, 'mapChange'); //this will trigger map update which will refresh page and hence all the widgets
}
}));
it is a page refresh but you no long have to deal with destroying, recreating dom as well as updating all the widget references to webmap
Hi,
May I know which .js file to change i.e what is the name of the .js file in which I am supposed to make these changes in the code?
Thanks,
Nikhil
Hello All,
I spent some time looking through the jimu.js folder specifically at the MapManager, LayoutManager and the WidgetManager to see how Esri manages with map and widget lifecycle. From this I have found the following solution.
When the user clicks on a button to load a new web map the following happens:
//The widget broadcasts a message that the map is about to be destroyed
topic.publish('beforeMapDestory', this.map);
//The map is destroyed
this.map.destroy();
//A new deffered object is created to handle the creation of a new webmap
var mapDeferred = jimuUtils.createWebMap(portalUrl, webMapItemId, mapContainerId, webMapOptions);
//The deffered is executed ensuring that the response is executed with "this" being the widget.js file
mapDeferred.then(lang.hitch(this, this._processNewMapSuccess), lang.hitch(this, this._processNewMapFail));
When the web map creation is complete the following function is executed:
//I set up the returned web map as a map object
var map = response.map;
map.itemId = this.appConfig.map.itemId;
map.itemInfo = response.itemInfo;
map.webMapResponse = response;
// enable snapping
var options = {
snapKey: keys.copyKey
};
map.enableSnapping(options);
//The widget gets a handle on the appConfig
var appConfig = this.appConfig
//The widget gets the configuration for the widget of interest
//This would need to be made dynamic but for testing I
//just simply grabbed the widget by its position in the array
var mapSwitcherWidgetConfig = appConfig.widgetPool.widgets[9]
//The widget changes the openAtStart propertie to true
mapSwitcherWidgetConfig.openAtStart = true
//The map is set as the applications map property
this.map = map;
//The widget broadcasts a message that the map has been changed
//The app builder handles all the magic from here
topic.publish('mapChanged', this.map);
One thing I haven't included in the code above is that you can change the intial map extent in the appConfig so that when the new web map loads its displayed at the extent that the user was previously viewing at.
Hope this helps everyone.
Regards
Sam
I was able to implement this code...partially. When I first open my map, I can click my drop down and choose the web map that I want to see and that works...once. But each time I try again, it will not change the web map. Chrome Dev tools show that the widgets are destroyed and that the "map changed" and then the widgets get recreated, but the map never changes.
Has anyone else experienced this?