Fix JavaScript error when navigating from map to weather page

Fixed "can't access property 'invalidateSize', e.map is undefined" error
that occurred when navigating away from the map page while a setTimeout
was still trying to access the destroyed map.

Changes:
- Added check for self.map and self.isDestroyed before invalidating map size
- Stored timeout references in a cleanupTimeouts array
- Added cleanup code in destroyed() function to clear all pending timeouts
- Updated TypeScript type definition to include cleanupTimeouts property

This prevents attempting to access the map object after it has been
destroyed during page navigation.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Graham McIntire 2025-07-20 08:19:51 -05:00
parent d3a5ed33f2
commit 15f3e8fcfe
No known key found for this signature in database
2 changed files with 24 additions and 2 deletions

View file

@ -603,7 +603,12 @@ let MapAPRSMap = {
}); });
// Check element dimensions after zoom // Check element dimensions after zoom
setTimeout(() => { const dimensionCheckTimeout = setTimeout(() => {
// Check if map still exists and not destroyed
if (!self.map || self.isDestroyed) {
return;
}
const afterRect = self.el.getBoundingClientRect(); const afterRect = self.el.getBoundingClientRect();
if (afterRect.width === 0 || afterRect.height === 0) { if (afterRect.width === 0 || afterRect.height === 0) {
@ -611,9 +616,17 @@ let MapAPRSMap = {
// Try to restore dimensions // Try to restore dimensions
self.el.style.width = "100vw"; self.el.style.width = "100vw";
self.el.style.height = "100vh"; self.el.style.height = "100vh";
self.map.invalidateSize(); if (self.map) {
self.map.invalidateSize();
}
} }
}, 1000); }, 1000);
// Store timeout for cleanup
if (!self.cleanupTimeouts) {
self.cleanupTimeouts = [];
}
self.cleanupTimeouts.push(dimensionCheckTimeout);
} }
}, 100); }, 100);
} catch (error) { } catch (error) {
@ -1620,6 +1633,14 @@ let MapAPRSMap = {
self.programmaticMoveTimeout = undefined; self.programmaticMoveTimeout = undefined;
} }
// Clear any dimension check timeouts
if (self.cleanupTimeouts !== undefined) {
self.cleanupTimeouts.forEach((timeout: number) => {
clearTimeout(timeout);
});
self.cleanupTimeouts = [];
}
// Remove popup navigation event listener // Remove popup navigation event listener
if (self.popupNavigationHandler) { if (self.popupNavigationHandler) {
document.removeEventListener('click', self.popupNavigationHandler); document.removeEventListener('click', self.popupNavigationHandler);

View file

@ -34,6 +34,7 @@ export interface LiveViewHookContext {
rfPathLines?: Array<Polyline | Marker>; // Array of Leaflet polylines and markers for RF path visualization rfPathLines?: Array<Polyline | Marker>; // Array of Leaflet polylines and markers for RF path visualization
trailLayer?: LayerGroup; trailLayer?: LayerGroup;
markerClusterGroup?: MarkerClusterGroup; markerClusterGroup?: MarkerClusterGroup;
cleanupTimeouts?: ReturnType<typeof setTimeout>[];
} }
export interface MarkerData { export interface MarkerData {