Replace web map in widget code?

8594
13
10-30-2014 12:26 PM
by Anonymous User
Not applicable

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?

Tags (2)
13 Replies
MelindaFrost
Occasional Contributor

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

0 Kudos
NikhilSharma
New Contributor II

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

0 Kudos
SamDrummond2
New Contributor III

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

EricMcPhee
New Contributor III

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?

0 Kudos