We've found that we have to set our api key on global config object or our application won't render (I'm assuming this is because the basemap is coming from our account). With this in place, we're able to let Users navigate around without any issues.
However, we allow Users to log into AGOL or one of their Enterprise portals, and that's when things get difficult. If they log into AGOL, we have to "unset" the api key (making it an empty string) in order to fetch their layers. If they log into an Enterprise portal, the apiKey doesn't matter, but the "config.portalUrl" must be set to the Enterprise's portalUrl. Because our application blocks the MapView while we grab the list of layers, it's manageable (though still messy code wise).
The real problem is when we attempt to load one of the layers, which we do with @ArcGIS/core/layers/Layer, calling the fromPortalItem function. Again, there's some global variable shuffling required, but because "fromPortalItem" is asynchronous, we've struggled to ensure the api key is set correctly during and after loading a layer. Even though we're passing the Users "token" to "fromPortalItem", we still have to move our config.apiKey out of the way. Here's (essentially) what we came up with to get layers to load:
const token = await getAuthToken();
if (isOnline && esriConfig.apiKey !== '') {
factory.setEsriApiKey('');
}
const portal = await factory.fromPortalItem({
portalItem: {
id: layerId,
apiKey: token,
portal: {
url: baseURL,
},
},
});
Has anyone else run into this? And if so, were you able to come up with a more maintainable solution?
If we're ever going to be able to load layers from AGOL and a User's Enterprise instance, this is going to become even more difficult to get right. I'm hoping maybe there's a hidden argument that can be passed to "fromPortalItem" to indicate it's an AGOL layer (though I'm not sure why the "baseURL" wouldn't be enough to make that determination). But, any suggestions or ideas are much appreciated!