Select to view content in your preferred language

Don't base map structure on API key validity

1096
2
08-03-2022 11:47 AM
Status: Closed
Labels (1)
DennisWelu1
Emerging Contributor

Prior to 100.14 the creation of a Map object with an AGOL basemap was done like this:

new Map(Basemap.CreateStreetsVector())

Starting with 100.14 the recommended new syntax for creating the same is now this:

new Map(new Basemap(BasemapStyle.ArcGISStreets))

The syntax changes is fine. But there is a behavior change also that impacts the integrity of the map structure.

Prior to 100.14, immediately after creating the map, you could inspect the new Map object and see that a basemap layer object is present. It isn't necessarily loaded yet...but structurally it is there represented. This allows independent parts of the application to look at the map structure and react accordingly. For example, if you were building a layer list UI you could see the basemap layer is present and represent it.

Starting with 100.14, if you inspect the new Map object the basemap layer you told it to start with just isn't even there. It only shows up when, and IF, the basemap layer loads. This makes it very difficult to build independent parts of an application that can inspect the map structure and build a UI around it accordingly. And if you happen to be offline (temporarily or part of an offline application) then the basemap never does load and show up in the structure.

After discussion with technical support it was explained that:

  • The reason the Basemap.CreateStreetsVector() is deprecated is because of the move to API Key accessed AGOL basemaps.
  • Basemap.CreateStreetsVector() initializes the basemap from a hard-coded list of basemap layers. Thus, the basemap layer can be returned as "loaded", since all layers are known.
  • Conversely, BasemapStyle initializes the basemap from a REST end point of basemap layers, protected by the API Key access. Thus, the basemap layer is not "loaded" automatically because it doesn't assume the required API Key authentication has taken place upon initial object creation.
  • The recommendation is to use the LoadAsync to insure the basemap layer loads and appears in the map's AllLayers list.

There are two replies I have to this answer.

  1. The "designed behavior" seems to be driven by the implementation of license checks instead of pure object-oriented structuring. If I add a layer to the map, then ask it what layers it has, I expect to see the layer I just added in the list...
  2. There already exists a status property for layers that captures the lifecycle of loading that could be used to determine its "load state". There may be various reasons the layer is taking time to load (e.g. authenticating, slow network, etc.). Layers can be in a Loading state, Loaded state, or could end up in an Error state. This seems like it could/should apply to basemap layers just the same regardless of licensing checks that may be happening in the background implementation. It seems reasonable to have the basemap layer be there upon inspection even if it's not loaded yet.
2 Comments
DiveshGoyal
Status changed to: Needs Clarification

If I add a layer to the map, then ask it what layers it has, I expect to see the layer I just added in the list

Adding a layer to a map does work the way you described.
However, the basemap style scenario you are discussing is entirely different.


It seems reasonable to have the basemap layer be there upon inspection even if it's not loaded yet.

No that is not possible. The definition of the basemap style resides in a backing REST webservice and not within the native api itslef.  The api needs to  determine the contents (layers) of the style asynchronously by consulting the backing service with a valid api key. This happens lazily during the load process. So the basemap needs to be loaded to populate it with the appropriate layers

DiveshGoyal
Status changed to: Closed