publiclab / Leaflet.DistortableImage

A Leaflet extension to distort or "rubber sheet" images
https://publiclab.github.io/Leaflet.DistortableImage/examples/
BSD 2-Clause "Simplified" License
273 stars 285 forks source link

map.remove() won't work when DistortableImage layers exist #1381

Open jpoep opened 1 year ago

jpoep commented 1 year ago

Describe the bug: When you try to remove the entire Leaflet map using map.remove(), leaflet-distortableimage will throw an error if there is any distortable image on the map:

grafik

We have an SPA that leaves us unable to correctly unmount the map when the user navigates away from the page, so this is rather unfortunate :(

Reproduce the behavior: See this minimal JSFiddle: https://jsfiddle.net/bwcvaeyk/1/

Open your browser's console and wait for a second for the map to unmount (JSFiddle's console swallows the message). You should see the same error as above.

Browser, version, and operating system:

Mustafa-Hersi commented 1 year ago

Have you found a workaround?

Raphyyy commented 1 year ago

Only workaround I could find is to catch map.remove() :

try {
    map.remove();
} catch (e) {}
jpoep commented 1 year ago

Only workaround I could find is to catch map.remove() :

try {
    map.remove();
} catch (e) {}

This won't properly unmount the map, though, because it cancels in the middle of the function. We did find a workaround, however. Sorry for not replying earlier!

/* eslint-disable @typescript-eslint/ban-ts-comment */
map.eachLayer(layer => {
  // @ts-ignore
  if (layer.editing) {
    // @ts-ignore
    const layers = layer.editing.currentHandle?._layers ?? {};
    // @ts-ignore
    Object.values(layers).forEach(layer => layer.remove());
    // @ts-ignore
    layer.editing.currentHandle = null;
  }
  layer.remove();
});
map.remove();
/* eslint-enable @typescript-eslint/ban-ts-comment */

Comments are obviously only useful if using TypeScript and/or ESLint :)

mota-b commented 3 months ago

Hi everyone i might have found the core issue here and a stable solution for it

The probleme

I think what is really causing the issue is either the layer containing the 4 corners of the distortable image overlay or the corners themselves When you try to unmount the container of the map component they might not be deleted properly (to be verified).

The proposed solution

The solution consist of removing the 4 corners of the distortable image overlay, then the layer containing them. Instead of removing all the layers of the map.

This can be done when -unmounting- the component containing the map I prefere to do it in in the -onRemove- callback of the image distortable overlay to easily get the -layerID- of my custom -overlay-