angular/components · error

Cannot interact with a MarkerClusterer before it has been in

Error message

Cannot interact with a MarkerClusterer before it has been initialized. Please wait for the MarkerClusterer to load before trying to interact with it.

What it means

DeprecatedMapMarkerClusterer stores the MarkerClustererInstance asynchronously after the map resolves. Any public API (fitMapToMarkers, getters/setters, etc.) funnels through _assertInitialized, which throws if markerClusterer is still undefined. It guards against touching the cluster before its async construction finished.

Source

Thrown at src/google-maps/deprecated-map-marker-clusterer/deprecated-map-marker-clusterer.ts:525

            this.markerClusterer.repaint();
            for (const marker of markersToRemove) {
              this._currentMarkers.delete(marker);
            }
          });
        });
      });
  }

  private _getInternalMarkers(
    markers: MapMarker[] | QueryList<MapMarker>,
  ): Promise<google.maps.Marker[]> {
    return Promise.all(markers.map(markerComponent => markerComponent._resolveMarker()));
  }

  private _assertInitialized(): asserts this is {markerClusterer: MarkerClustererInstance} {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (!this.markerClusterer) {
        throw Error(
          'Cannot interact with a MarkerClusterer before it has been initialized. ' +
            'Please wait for the MarkerClusterer to load before trying to interact with it.',
        );
      }
    }
  }
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Wait for the map/cluster to load before interacting — e.g. await mapComponent._resolveMap() first.
  2. Defer API calls until after a tick/subscription indicating the cluster is ready.
  3. In tests, await a stable state (e.g. whenStable or a promise) before assertions.
  4. Migrate to @googlemaps/markerclusterer which exposes clearer lifecycle APIs.

Example fix

// before
ngAfterViewInit() { this.cluster.fitMapToMarkers(); }
// after
async ngAfterViewInit() {
  await this.map._resolveMap();
  this.cluster.fitMapToMarkers();
}
Defensive patterns

Strategy: try-catch

Validate before calling

async function whenClusterReady(cluster: any) {
  await cluster._resolveMap?.();
  if (!cluster.markerClusterer) throw new Error('MarkerClusterer not ready yet');
}

Type guard

function isClusterReady(c: any): c is {markerClusterer: NonNullable<typeof c.markerClusterer>} {
  return c?.markerClusterer != null;
}

Try / catch

try {
  this.cluster.fitMapToMarkers();
} catch (e) {
  if (String((e as Error).message).includes('before it has been initialized')) {
    this.cluster._resolveMap().then(() => this.cluster.fitMapToMarkers());
  }
}

Prevention

When it happens

Trigger: Calling fitMapToMarkers, get/set averageCenter, batchSizeIE, calculator, clusterClass, etc. immediately after creating the component, before _resolveMap().then(...) has assigned this.markerClusterer.

Common situations: Calling cluster APIs in ngOnInit/ngAfterViewInit of a parent before the promise resolves; interacting in tests without awaiting initialization; slow Google Maps script loading delaying map resolution.

Related errors


AI-assisted analysis of angular/components@0411926e7d (2026-08-31). Data as JSON: /api/errors/c7036460364edda3. Report an issue: GitHub.