Freika/dawarich · warning

Maps controller or placesManager not found

Error message

Maps controller or placesManager not found

What it means

The places filter controller reads a global window.mapsController and warns when it (or its placesManager) is missing. Critically, nothing in this codebase ever assigns window.mapsController — the Maps V2 controller is a Stimulus controller and is never exposed on window — so this guard fails by design and tag-based place filtering never runs. It is a stale global-variable contract left over from an older map implementation.

Source

Thrown at app/javascript/controllers/places_filter_controller.js:12

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  connect() {
    console.log("Places filter controller connected")
  }

  filterPlaces(_event) {
    // Get reference to the maps controller's placesManager
    const mapsController = window.mapsController
    if (!mapsController || !mapsController.placesManager) {
      console.warn("Maps controller or placesManager not found")
      return
    }

    // Collect all checked tag IDs
    const checkboxes = this.element.querySelectorAll(
      'input[type="checkbox"][data-tag-id]',
    )
    const selectedTagIds = Array.from(checkboxes)
      .filter((cb) => cb.checked)
      .map((cb) => parseInt(cb.dataset.tagId, 10))

    console.log("Filtering places by tags:", selectedTagIds)

    // Filter places by selected tags (or show all if none selected)
    mapsController.placesManager.filterByTags(
      selectedTagIds.length > 0 ? selectedTagIds : null,
    )
  }

View on GitHub (pinned to 97fad417c5)

Solutions

  1. Replace the window global with a Stimulus lookup, mirroring the realtime controller: this.application.getControllerForElementAndIdentifier(mapElement, "maps--maplibre") where mapElement is the map container (query '[data-controller~="maps--maplibre"]').
  2. Alternatively have maplibre_controller expose itself via a custom event or a dispatched callback that the filter controller listens for, removing the global entirely.
  3. If a quick shim is needed, assign window.mapsController = this inside maplibre_controller.connect() — but prefer the Stimulus lookup.

Example fix

// before
const mapsController = window.mapsController
if (!mapsController || !mapsController.placesManager) {
  console.warn("Maps controller or placesManager not found")
  return
}

// after
const mapElement = document.querySelector('[data-controller~="maps--maplibre"]')
const mapsController =
  mapElement &&
  this.application.getControllerForElementAndIdentifier(mapElement, "maps--maplibre")
if (!mapsController || !mapsController.placesManager) {
  console.warn("Maps controller or placesManager not found")
  return
}
Defensive patterns

Strategy: validation

Validate before calling

const el = document.querySelector('[data-controller~="maps--maplibre"]')
const ctrl =
  el && this.application.getControllerForElementAndIdentifier(el, "maps--maplibre")
if (!ctrl?.placesManager) return

Prevention

When it happens

Trigger: Any interaction that invokes filterPlaces (changing a place-tag checkbox) on a page where the filter controller is connected: window.mapsController is undefined in every case because no code sets it, so the warning fires and filtering is a no-op.

Common situations: After migrating from a legacy map that exported a window global to the Maps V2 Stimulus architecture; new tag-filter UI wired to this controller; devs assuming the map controller self-registers globally as in older versions.

Related errors


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