styledata event can cause "Style is not done loading"
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
**mapbox-gl-js version**: 1.10.2
**browser**: various from Sentry: Firefox 77 / Mobile Safari 13 / Edge 16 / Firefox Mobile 67 / Chrome 59
### Steps to Trigger Behavior
1. Initialize the map with an empty style.
2. After the load event, call setStyle() with an actual style (url or object)
3. add a source in a styledata callback
```
map.once('styledata', _ => {
map.addSource(...) // => "Style is not done loading"
})
```
The setStyle could even be an empty style with {diff: false}, meaning nothing is loaded at all, it'd still trigger the bug!
### Link to Demonstration
I cannot reproduce it locally, but it's showing up in Sentry issues quite a lot.
### Expected Behavior
It should be possible to add a source in a `styledata` event callback, as the style should be loaded at that time.
By the documentation, `styledata` event should only trigger once the style has loaded. `styledataloading` is the event which should trigger once the style starts loading, but hasn't loaded yet.
### Actual Behavior
`styledata` is not working correctly, as it can be triggered before the style has finished loading. Cannot reproduce it locally, but it is happening to many users in Sentry.
The bigger problem here is that I'd like to know what is a reliable way to detect style load events. I'd like to dynamically switch styles and add a source after each switching. Basically https://docs.mapbox.com/mapbox-gl-js/example/setstyle/ + adding a source.
StackOverflow is full of weird workarounds for this or very similar issues.
- using setTimeout + isStyleLoaded in a loop
- recommending `style.load` event (officially not supported)
- recommending `idle` (which would make the whole app super slow, as it wouldn't just wait for the style to load but for all tiles to finish loading)
Even issues here have many recommendation for setTimeout + isStyleLoaded or other weird workarounds.
It just feels very much not on the otherwise super high standard of this library that such basic functionality is not working correctly. Dynamic style switching + adding custom sources must be like one of the most common use cases of Mapbox GL JS, I'm really surprised it has so many issues around it. Personally I find the cleanest to use `style.load` but then it's not official for some reason.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the styledata event entry point and the setStyle/addSource lifecycle described in the reproduction steps. Try to reproduce the empty-style-to-setStyle sequence, then inspect when style loading is marked complete relative to styledata emission. Done means adding a source from the styledata callback succeeds reliably, with a regression test covering the sequence.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100