Open shaiRos opened 3 weeks ago
Thank you for reporting this issue (and doing a well-written writeup).
I am able to reproduce this by spinning up an npm create vite reproduce-example-project
with react and typescript, installing everything, and trying to use VectorTileLayer
.
This is extremely odd. I have no had this issue when using parcel or webpack. Let me do some digging and see if I can come up with anything as to why using this library with vite creates this issue.
Have you tried using the "vanilla" version of a VectorTileLayer with Vite? Does that work? If that causes the same problem, it helps debug whether the issue in is this wrapper library, or upstream somewhere.
sigh so this problem is very strange indeed. Looking into it, the author of leaflet answered another person with the same here: Cannot read property '_leaflet_id' of undefined:
This happens when tilelayer variable is undefined at the moment when this line executes. Put a debugger statement there and figure it out, shouldn't be hard.
Digging into the leaflet src code, when the map.removeLayer event fires, if the layer
that is being removed doesn't exist, this will happen because of this:
IMO this is a small area where the leaflet src code could probably be improved. I don't personally understand why removeLayer
is firing at all, or why its firing with an undefined
layer in this particular use case. However, a workaround for now is to do this: in your code, anywhere after importing leaflet, but before using a VectorTileLayer, add this:
L.Map.include({
removeLayer(layer: L.Layer) {
if (!layer) return this;
const id = L.Util.stamp(layer);
if (!this._layers[id]) {
return this;
}
if (this._loaded) {
layer.onRemove(this);
}
delete this._layers[id];
if (this._loaded) {
this.fire("layerremove", { layer });
layer.fire("remove");
}
// @ts-expect-error leaflet TS very incomplete
layer._map = layer._mapToAdd = null;
return this;
},
});
This will overwrite the Map.removeLayer method to not call stamp
on smething that is undefined, thereby avoiding the code that would throw an error.
This is a hacky workaround, but it does work. I am trying to brainstorm why leaflet code would ever get to running Map.removeLayer on something that is undefined, in this case only. There is something under the hood of react-leaflet with createLayerComponent
that may be causing this, but I'm not sure what.
If you are familiar with these things, I'm open to suggestion on what could be going wrong or how to fix it, but for now, at least you have a monkeypatch solution.
Another thought
React 18 renders everything twice when using React.StrictMode
, which is a default part of a vite project (ew). While it can actually help debug problems, in this case, I think the issue is that react is mounting and unmounting the VectorTileLayer
too quickly, and the underlying leaflet layer is not being created in time.
Completely separately from the other solution I posted, removing StrictMode solves the problem for me as well. Perhaps this is not a vite
issue, but rather a react-esri-leaflet issue when using strictmode in react 18.
Thanks! removing the strictmode worked (and the previous solution too). I did notice when i ran the preview of (npm run build) by vite, the app ran without errors with the VectorTile line in the code, but the layer was still not added to the map. And running on build preview removes that behavior relating to strict mode...
I have an app created with vite. Installed this library and I'm trying to use a vector tile to display in the map. I have tried the url used for the example for this library and even from the esri documentation here for vector tiles. Even created another repo where it's just the base template that vite installs (react-javascript)
and it's giving me this main error Uncaught TypeError: Cannot use 'in' operator to search for '_leaflet_id' in undefined
Things I tried:
help would be apprecitated.