I'm working on an application that saves part of the app state with a link and URL parameters like a marker, zoom, and base map that can be shared with others. For certain base maps I can just use code like:
viewElement.map.basemap = basemapShortNameThis works fine for Imagery, Imagery Hybrid, Streets, Topographic and others that seem to have the short Name logic baked into the basemap class. Some of the other short names like osm (Open Street Map) seem to reference another base map that is different from the Basemap widget though when it is selected there. For these, I am trying to reference the portal item in ArcGIS Online.
When I reference the item in ArcGIS Online in the javascript for my application, I get errors like the below:
[esri.Basemap] #load() Failed to load basemap (title: 'Basemap', id: '19a35e6774b-basemap-39')
Unable to load http://127.0.0.1:5500/null/data?f=json status: 404
This is the definition I have for the basemap portal item:
const basemap = {
portalItem: {
id: "c29cfb7875fc4b97b58ba6987c460862",
portal: {
url: "https://www.arcgis.com"
}
}
};
viewElement.map.basemap = basemap;Even though I have the URL for arcgis.com, it still seems to try to be loaded from my local machine.
Using the above approach works fine and expected from developer console in the browser.
How do I successfully change to one of these ArcGIS Online base map portal items in my application as it loads to restore one that was previously selected?
Solved! Go to Solution.
It turns out that I didn't need to set a portal config after all. In my code I have an object of basemaps to choose from and I was pulling in the wrong value from there for the portalID. This is an example of what worked in the end for the Open Street Map basemap:
const basemap = {portalItem: {id: baseMapLookup[savedBasemap]["portalID"]}} or
const basemap = {portalItem: {id: "c29cfb7875fc4b97b58ba6987c460862"}}
I was accessing my "portalID" property in the wrong way.
Thanks for taking the time to pose some solutions! That got me looking at my code some more and helped me to find my own mistakes.
Hi Jason,
What happens if you try using the Basemap Class Constructor instead of autocasting from the object? It definitely seems odd to me that it would make that request to your local machine!
Unfortunately, the Basemap class constructor throws the same error with this code:
const basemap = new Basemap({
portalItem: {
id: "c29cfb7875fc4b97b58ba6987c460862",
portal: {
url: "https://www.arcgis.com"
}
}
});
Bump. Does anyone from ESRI have a suggestion for how to specify ArcGIS Online as the portal for my custom application besides specifying the url for the portal object when using the Basemap constructor? It looks like the basemap is trying to be accessed from my local machine by the error: Unable to load http://127.0.0.1:5500/null/data?f=json status: 404 .
Have you tried dropping the portal property altogether? For most AGOL items you can just do something like:
const basemap = new Basemap({
portalItem: {
id: "c29cfb7875fc4b97b58ba6987c460862"
}
});
view.map.basemap = basemap;I wonder if the portal property is throwing it off somehow.
I get the same error when omitting the portal object. I think I tried referencing the basemap without the portal object on my first attempts. After it didn't work, I did some research and thought adding a portal object with the URL might help. It seems like I need to set my portal somewhere else though since it is still trying to load from my local machine.
Interesting. Have you tried setting the portal globally and then just using a Portaltem?
import esriConfig from "@arcgis/core/config";
import Map from "@arcgis/core/Map";
import MapView from "@arcgis/core/views/MapView";
import Basemap from "@arcgis/core/Basemap";
import PortalItem from "@arcgis/core/portal/PortalItem";
esriConfig.portalUrl = "https://www.arcgis.com";
const map = new Map({
basemap: "topo-vector"
});
const view = new MapView({
container: "viewDiv",
map
});
view.when().then(() => {
const params = new URLSearchParams(window.location.search);
const basemapId = params.get("basemapId"); // throw the basemap id here
if (basemapId) {
const bm = new Basemap({
portalItem: new PortalItem({
id: basemapId
})
});
view.map.basemap = bm;
}
});
It turns out that I didn't need to set a portal config after all. In my code I have an object of basemaps to choose from and I was pulling in the wrong value from there for the portalID. This is an example of what worked in the end for the Open Street Map basemap:
const basemap = {portalItem: {id: baseMapLookup[savedBasemap]["portalID"]}} or
const basemap = {portalItem: {id: "c29cfb7875fc4b97b58ba6987c460862"}}
I was accessing my "portalID" property in the wrong way.
Thanks for taking the time to pose some solutions! That got me looking at my code some more and helped me to find my own mistakes.
Awesome! Glad you were able to get it sorted.