Determine when map tiles have been downloaded

1130
6
01-05-2018 10:35 AM
yangwen
New Contributor III

I need to overlay the map container with a loading spinner before the map is ready for view and interaction.  To that end, the completion of basemap tiles download is necessary

Is there a property of Map, MapView, or Basemap that will provide that insight?  When I watch the basemap.loaded property, it changes to true even before the requests for the pbf files.

Tags (2)
0 Kudos
6 Replies
RobertScheitlin__GISP
MVP Emeritus

Yang,

   You need to put a watch on the views updating property.

https://developers.arcgis.com/javascript/latest/api-reference/esri-views-MapView.html#updating 

yangwen
New Contributor III

Ok I'm watching that property..  Yes I can see that eventually the updating value changes to false once the pbfs are downloaded.  However from page load to pbf download completion, the updating property toggles between true and false multiple times, making it difficult to figure out the exact toggle that I want to act on. 

I've tried to also use it in combination with the basemap properties to identify the final toggle of updating.  However they are none distinguishable.

My watcher function provides the following output between page load and completion of pbf requests.

mapView.watch('updating', view => {
console.log('view updating', view, 'basemap Status', this.map.basemap.loadStatus);
});


view updating false basemap Status loaded
view updating true basemap Status loaded
view updating false basemap Status loaded
view updating true basemap Status loaded
view updating false basemap Status loaded

The updating toggles occur in quick succession, so I could implement the spinner logic in a timer to capture the final state of the updating property but that seems a bit hackish.  I'm thinking there has to be another property I can use in combination to precisely identify completed download of map tiles.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Yang,

  See if this works for you:

      view.when(function(){
        watchUtils.whenFalse(view.basemapView.baseLayerViews.getItemAt(0), 'updating', updating => {
          if(view.stationary){
            console.log('Done Updating');
          }else{
            watchUtils.whenTrueOnce(view, "stationary", still => {
              console.log('Done Updating');
            });
          }
        });
      });
yangwen
New Contributor III

'Done Updating' does not print for me.  I'm also providing output below that intermixes output from a view.stationary watcher.

dcp-map.component.ts:188 view updating true basemap Status loaded
14:08:19.840 dcp-map.component.ts:202 view stationary now zoom 9 scale 577790.554289 center -11570638.932396324, 3836411.2886857823 extent {__accessor__: b}
14:08:20.133 dcp-map.component.ts:188 view updating false basemap Status loaded
14:08:24.835 dcp-map.component.ts:188 view updating true basemap Status loaded
14:08:25.149 dcp-map.component.ts:188 view updating false basemap Status loaded

Very obscure lifecycle behavior.  None of this is documented huh, I couldn't find any?  I wish they have implemented first class events.. would avoid a lot of this property watching spaghetti logic.

Edit: It also appears the updating property toggles when the map is panned and more basemap tiles are requests.  This makes sense.  However I also need to separate the post-initial load updating activities from the updating activities that's part of the initial load.  The initial load is typically much slower, and thus requires some UI indicator.  Subsequent tile downloads from pan or zoom actions are much quicker and no progress indicator is needed.

I can manage this manually outside of the arcgis instances, but are there flags or other properties to denote post initial loading?

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Yang,

  Strange it worked for me.

0 Kudos
yangwen
New Contributor III

Probably due to differences in our map's features make up.. I'll keep looking into it.  Appreciate the sample code!

0 Kudos