How do I change the basemap programmatically?

4302
7
12-21-2019 05:38 PM
JoseVidal
New Contributor III

I am building a custom widget for WAB. To start with, I just want to build a button that switches between the 'streets' and the 'topo' basemap.

I created a working widget and in it I have this code:

let newMap = new Map("map", {
  basemap: "streets",
  center: [-105.255, 40.022],
  zoom: 13
});
console.log("newMap")
console.log(newMap)
this.map = newMap

Which creates a new Map, and does not generate any errors, but also does not change the map.

I am guessing I need to do more than just `this.map = newMap`. But, what?

There is no documentation on this.

0 Kudos
7 Replies
shaylavi
Esri Contributor

Jose,

You should not recreate the map object unless you plan to display multiple map views.

To change a basemap you use the existing map object and use the function setBasemap

map.setBasemap("name_of_the_basemap");

alternatively, you can use the toggle widget that has this functionality built-in -

Basemap Toggle | ArcGIS API for JavaScript 3.31 

or the basemap gallery widget, which is similar -

Basemap gallery | ArcGIS API for JavaScript 3.31 

Shay.

Shay
RobertScheitlin__GISP
MVP Emeritus

Here is a link to a thread about issues trying to use the JS API basemap toggle widget in WAB.

https://community.esri.com/thread/161760#comment-534257 

Here is how we switch a basemap in the custom Local Layer widget.

var bmLayerObj = {
  url: url,
  isReference: false
};
var _newBasemap = new Basemap({
  id: 'defaultBasemap',
  title: "blah blah",
  layers: [new BasemapLayer(bmLayerObj)]
});
var _basemapGallery = new BasemapGallery({
  showArcGISBasemaps: false,
  map: this.Map
});
_basemapGallery.add(_newBasemap);
_basemapGallery.select('defaultBasemap');
_basemapGallery.destroy();
JoseVidal
New Contributor III

That worked! Thanks! 

I only had to change line 12 to: map: this.map. Uppercase this.Map does not work.

But, I am executing a printtask right after changing the basemap and the print uses the old map. I am guessing it is because I have to wait until the basemap has changed before a call the printtask.

Is there a way to get a callback (setup a .then()) for after the basemap changes?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus
JoseVidal
New Contributor III

Thanks! That worked.

0 Kudos
JoseVidal
New Contributor III

I used the line:

this.map.setBasemap("topo");

but, it does not do anything. The map remains the same. It does not produce an error either.

I will try Scheitlin's solution next.

0 Kudos
Adarshvarma
New Contributor

Jose,

it sets the base map at a particular zoom level, but again it vanishes after we change the zoom level

0 Kudos