-
Notifications
You must be signed in to change notification settings - Fork 606
Description
due to third-argument map.on options being misinterpreted as layerIds
Environment
MapLibre GL JS v5.x (MapLibre)
@mapbox/mapbox-gl-draw v1.4.0
Mobile/touch devices (touchstart events)
Observed error
Uncaught TypeError: t2.filter is not a function
at Map._createDelegatedListener (map.ts:1445)
at Map.fire (evented.ts:132)
at ...
at MapEventHandler.touchstart (map_event.ts:70)Root cause analysis
On touch devices, Mapbox GL Draw registers events like:
map.on('touchstart', handler, { passive: true })MapLibre GL JS v5 Map#on does not support a third options argument. { passive: true }
ref: MapLibre on API
The third argument is mis-parsed, so layerIds becomes the handler function instead of an array.
In MapLibre’s _createDelegatedListener, it executes layerIds.filter(...), causing filter is not a function.
Why it only happens on mobile
The offending path is triggered by touch events (touchstart, etc.), which are used only on mobile devices.
Workaround (for MapLibre users)
Patch map.on to ignore the 3rd argument when the 2nd argument is the listener function, or modify Draw’s event registration to not pass { passive: true } with MapLibre.
Suggested fix in Draw
Detect MapLibre (or check for map.on signature) and avoid passing third argument options:
map.on('touchstart', handler) instead of map.on('touchstart', handler, { passive: true }).
Temporary fix
private patchMapEventOptions(map: maplibregl.Map): maplibregl.Map {
// Normalize map.on signature to tolerate third-arg options from Mapbox Draw.
const originalOn = map.on.bind(map)
map.on = ((type: string, layerIds: unknown, listener?: unknown) => {
if (typeof layerIds === 'function' && listener && typeof listener === 'object') {
// @ts-expect-error hackly used
return originalOn(type, layerIds)
}
// @ts-expect-error hackly used
return originalOn(type, layerIds as string | string[], listener as maplibregl.Listener)
}) as maplibregl.Map['on']
return map
}