Freika/dawarich · warning

[Realtime Controller] Map not available for zooming

Error message

[Realtime Controller] Map not available for zooming

What it means

zoomToPoint guards on !mapsController || !mapsController.map before calling map.flyTo. The map property only exists after maplibregl.Map construction finishes inside the maps controller's async initialization, so this warning means a zoom request (e.g. live-mode jump to newest point or a replay seek) arrived before the MapLibre GL map instance was created. The zoom is silently skipped.

Source

Thrown at app/javascript/controllers/maps/maplibre_realtime_controller.js:290

      mapsController.layerManager?.getLayer("recentPoint")
    if (!recentPointLayer) {
      console.warn("[Realtime Controller] Recent point layer not found")
      return
    }

    if (this.liveModeEnabled) {
      recentPointLayer.show()
      recentPointLayer.updateRecentPoint(longitude, latitude, properties)
    }
  }

  /**
   * Zoom map to a specific point
   */
  zoomToPoint(longitude, latitude) {
    const mapsController = this.mapsV2Controller
    if (!mapsController || !mapsController.map) {
      console.warn("[Realtime Controller] Map not available for zooming")
      return
    }

    const map = mapsController.map

    map.flyTo({
      center: [longitude, latitude],
      zoom: Math.max(map.getZoom(), 14),
      duration: 2000,
      essential: true,
    })
  }

  /**
   * Update connection indicator (no-op, badge removed)
   */
  updateConnectionIndicator(_connected) {}
}

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Queue the zoom request (store target coords) and execute it on the MapLibre map's first 'load' event, so early broadcasts are not lost.
  2. Only call zoomToPoint after the map controller dispatches its ready state; check mapsController.map upfront at the call site.
  3. If map stays undefined permanently, check the browser console for MapLibre init errors (missing style, invalid container) and fix those first.

Example fix

// before
zoomToPoint(longitude, latitude) {
  const mapsController = this.mapsV2Controller
  if (!mapsController || !mapsController.map) {
    console.warn("[Realtime Controller] Map not available for zooming")
    return
  }
  ...
}

// after
zoomToPoint(longitude, latitude) {
  const mapsController = this.mapsV2Controller
  if (!mapsController || !mapsController.map) {
    this.pendingZoom = [longitude, latitude]
    return
  }
  ...
}
// on map 'load': if (this.pendingZoom) { const [lo, la] = this.pendingZoom; this.zoomToPoint(lo, la) }
Defensive patterns

Strategy: fallback

Validate before calling

const m = this.mapsV2Controller?.map
if (!m) { this.pendingZoom = [longitude, latitude]; return }

Prevention

When it happens

Trigger: A realtime broadcast or UI action invokes zoomToPoint during page load before maplibre_controller has assigned this.map; or the map controller exists but failed to initialize its map (bad container, missing token/style error) leaving map undefined while live mode keeps calling zoom.

Common situations: Live mode auto-zoom enabled with a phone uploading points the moment the page opens; map container hidden at init (display:none tab) preventing MapLibre setup; style URL failure so map never instantiates yet realtime handlers keep firing.

Related errors


AI-assisted analysis of Freika/dawarich@97fad417c5 (2026-08-21). Data as JSON: /api/errors/d7c061f78c65af36. Report an issue: GitHub.