mapbox-gl-js icon indicating copy to clipboard operation
mapbox-gl-js copied to clipboard

map.isStyleLoaded() is unreliable

Open stepankuzmin opened this issue 5 years ago • 11 comments

Steps to Trigger Behavior

  1. create map with load event handler
  2. change style with setStyle
  3. load event is not emitted

Link to Demonstration

https://jsfiddle.net/StepanKuzmin/jq2goby8/

Expected Behavior

load event handler called after new style done loading

Actual Behavior

load event handler is not called after new style done loading

stepankuzmin avatar Aug 26 '19 13:08 stepankuzmin

I've created a PR for this https://github.com/mapbox/mapbox-gl-js/pull/8692

stepankuzmin avatar Aug 26 '19 13:08 stepankuzmin

I think it's working as designed — from the docs:

Fired immediately after all necessary resources have been downloaded and the first visually complete rendering of the map has occurred.

Maybe you're looking for the styledata event instead?

mourner avatar Aug 27 '19 11:08 mourner

Hey @mourner! Thanks for the reply!

The problem with styledata is that after changing map style with setStyle, there is no way (as far as I know) to catch map in loaded state.

Calling map.isStyleLoaded() in styledata event handler always resolves to false.

Consider example: https://jsfiddle.net/StepanKuzmin/gojspc4t/

stepankuzmin avatar Aug 27 '19 11:08 stepankuzmin

@stepankuzmin should we fix isStyleLoaded instead of changing the semantics of load then?

mourner avatar Aug 27 '19 11:08 mourner

Well, yes. If it is intended to fire load event only once during map lifecycle, then it would be good to detect if map style is loaded after changing it using styledata event handler.

stepankuzmin avatar Aug 27 '19 11:08 stepankuzmin

This would be really good to fix. I have been running into variants of this bug for the past two years of developing maps with mapbox-gl-js. I can confirm the current issue is that map.isStyleLoaded() is very unreliable, and if it is false then it is not clear what event you can listen to for when it is true again. E.g. if I listen to styledata then sometimes the last event isStyleLoaded() is false, and if I listen to sourcedata then isStyleLoaded() seems to randomly switch between true and false

gmaclennan avatar Sep 06 '19 13:09 gmaclennan

I've been able to attach a handler on the style.load event instead of load to know when it is safe to update the map after calling map.setStyle().

It's been working fine for us since early 2018, but it is an undocumented event type.

For context, we use this to let users switch their base map. Our system sets the new style url, then waits for this event before adding back their style layers.

DannyDelott avatar Sep 10 '19 21:09 DannyDelott

Related issue we need to cover when fixing this: #4849

mourner avatar Sep 11 '19 17:09 mourner

@mourner For what it's worth we just ran into this after enabling RGB terrain in our Mapbox style. We weren't able to figure out a resolution to it and had to go back to the legacy hill shading which was a bummer. Both isStyleLoaded and areTilesLoaded just remained at false indefinitely. Things all of a sudden breaking based on what we assumed would be just underlying cosmetics in Studio is definitely concerning.

leigeber avatar Mar 02 '20 00:03 leigeber

I'm running into this again. Specifically: a state where map.isStyleLoaded() returns false, and yet the styledata event never fires. Sample log (edited output from Chrome console):

// at this point, execution is paused
> map.isStyleLoaded()
18:32:12.423 false

> map.once('styledata', ()=> console.log(999))
18:32:53.629 r {_moving: false, _zooming: false, transform: go, _bearingSnap: 7, _renderFrameCallback: ƒ, …}

// we unpause

18:33:12.690 map.isStyleLoaded()
18:33:12.703 true

// notice the event never happened

This is with mapbox-gl-js 1.6.1.

It would be really great to have a reliable mechanism for manipulating the style that will either happen immediately, or at a later time if needed. This is probably my biggest frustration with mapbox-gl-js.

stevage avatar Apr 21 '20 08:04 stevage

I'm running into this again. Specifically: a state where map.isStyleLoaded() returns false, and yet the styledata event never fires.

Is the any resolution for this in the pipeline? Or to at least to clarify how it currently works in the documentation?

cWillow avatar Dec 20 '22 14:12 cWillow

Hi everyone! We've added the documentation for the style.load event here https://github.com/mapbox/mapbox-gl-js/pull/12600

The style.load event is fired immediately after all style resources have been downloaded and the first visually complete rendering of the base style has occurred.

map.on('style.load', () => {
  console.log('style resources have been downloaded');
});

I'm closing the issue, but feel free to tag me if you have any questions.

stepankuzmin avatar Mar 28 '23 16:03 stepankuzmin