Tile layer source is invalid if layer is made visible quickly after changing the map style
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 12.4k
- Forks
- 2.4k
- PR merge metrics
- No merged PRs in 30d
Description
Hi all. I come with a particular bug that happens in the use that I give to mapbox.
**Scenario:** In the application that I develop we have the option to change the style of the map at any time. After doing so, we perform the operation of recreating all the previously existing objects on the map since they are deleted on a style change. Being these sources and layers, and make visible those layers that were so before changing the style.
**mapbox-gl-js version**: **v2.5.1**
**vue**: **~2.6**
**Bug:** To explain well the bug here I let little setup that I'm doing:
```
let style = "mapbox://styles/mapbox/streets-v9";
let sourceId = "source-id-1234";
let source = {
params: "&field=employment_capacity",
type: "vector",
tiles: ["http:localhost:3001/tiles/layers/731/{z}/{x}/{y}"],
};
let layer = {
id: "layer-id-1234",
type: "fill",
source: "source-id-1234",
"source-layer": "features",
layout: {
visibility: "none",
},
paint: {
"fill-color": "#ff0000",
"fill-opacity": 0.5,
"fill-antialias": false,
},
};
let afterLoadStyle = () => {
map.addSource(sourceId, source);
map.addLayer(layer);
map.setLayoutProperty(layer.id, "visibility", "visible");
};
map.on("style.load", afterLoadStyle);
map.setStyle(style);
```
So the error is that after changing the map style the `afterLoadStyle` function is triggered, it creates the layer object defined above and makes it visible.
But assuming that the application is running on `http://localhost:8000`, and as you can see the source for the tiles is defined as: `http:localhost:3001/tiles/layers/....`. What happens is that the actual tiles requests created after the style is changed, are being done to the URL: `http://localhost:8000/localhost:3001/tiles/layers/...`. In other words, is concatenating the tile source URL, to the site URL.
I'm currently doing a workaround of this issue by just adding a delay on the creation of the layer, after the new map style is loaded. Meaning that the function `afterLoadStyle` now is:
```
let afterLoadStyle = () => {
setTimeout(() => {
map.addSource(sourceId, source);
map.addLayer(layer);
map.setLayoutProperty(layer.id, "visibility", "visible");
}, 1000);
};
```
With this change, it seems that is working with no issue. But neither way is not the ideal scenario. Bellow ill attach a demonstration of the issue:
**Demonstration:**
https://user-images.githubusercontent.com/21204940/143035212-addb6eee-85b7-4afb-900f-02b3fc5ba7e7.mp4
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 reproducing the v2.5.1 example around setStyle, the style.load handler, addSource, addLayer, and setLayoutProperty, then inspect the tile requests when visibility is changed immediately versus after the delay. Done means the configured tile URL is requested directly after a style change without requiring a timeout, while preserving the demonstrated source and layer setup.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, typescript
- Domain
- frontend, web-dev
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100