From 15f3e8fcfec0776661c8cab9bded42ffc0d96562 Mon Sep 17 00:00:00 2001 From: Graham McIntire Date: Sun, 20 Jul 2025 08:19:51 -0500 Subject: [PATCH] Fix JavaScript error when navigating from map to weather page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- assets/js/map.ts | 25 +++++++++++++++++++++++-- assets/js/types/map.d.ts | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/assets/js/map.ts b/assets/js/map.ts index ada52d9..73e1815 100644 --- a/assets/js/map.ts +++ b/assets/js/map.ts @@ -603,7 +603,12 @@ let MapAPRSMap = { }); // 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(); if (afterRect.width === 0 || afterRect.height === 0) { @@ -611,9 +616,17 @@ let MapAPRSMap = { // Try to restore dimensions self.el.style.width = "100vw"; self.el.style.height = "100vh"; - self.map.invalidateSize(); + if (self.map) { + self.map.invalidateSize(); + } } }, 1000); + + // Store timeout for cleanup + if (!self.cleanupTimeouts) { + self.cleanupTimeouts = []; + } + self.cleanupTimeouts.push(dimensionCheckTimeout); } }, 100); } catch (error) { @@ -1620,6 +1633,14 @@ let MapAPRSMap = { 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 if (self.popupNavigationHandler) { document.removeEventListener('click', self.popupNavigationHandler); diff --git a/assets/js/types/map.d.ts b/assets/js/types/map.d.ts index a6e2eab..8df971a 100644 --- a/assets/js/types/map.d.ts +++ b/assets/js/types/map.d.ts @@ -34,6 +34,7 @@ export interface LiveViewHookContext { rfPathLines?: Array; // Array of Leaflet polylines and markers for RF path visualization trailLayer?: LayerGroup; markerClusterGroup?: MarkerClusterGroup; + cleanupTimeouts?: ReturnType[]; } export interface MarkerData {