angular/components · error

Cannot interact with a Google Map Directions Renderer before

Error message

Cannot interact with a Google Map Directions Renderer before it has been initialized. Please wait for the Directions Renderer to load before trying to interact with it.

What it means

This error is thrown by the MapDirectionsRenderer component's dev-mode assertion when its internal google.maps.DirectionsRenderer object is still undefined. The Angular Google Maps wrapper creates the renderer asynchronously (after the Google Maps API loads and the component initializes), so any interaction before that is invalid. It exists to give a clear message instead of an opaque 'undefined is not a function' failure.

Source

Thrown at src/google-maps/map-directions-renderer/map-directions-renderer.ts:165

    this._assertInitialized();
    return this.directionsRenderer.getRouteIndex();
  }

  private _combineOptions(): google.maps.DirectionsRendererOptions {
    const options = this._options || {};
    return {
      ...options,
      directions: this._directions || options.directions,
      map: this._googleMap.googleMap,
    };
  }

  private _assertInitialized(): asserts this is {
    directionsRenderer: google.maps.DirectionsRenderer;
  } {
    if (typeof ngDevMode === 'undefined' || ngDevMode) {
      if (!this.directionsRenderer) {
        throw Error(
          'Cannot interact with a Google Map Directions Renderer before it has been ' +
            'initialized. Please wait for the Directions Renderer to load before trying ' +
            'to interact with it.',
        );
      }
    }
  }
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Wait for component readiness before calling accessors: subscribe to the map's/overlay's ready output or wrap calls in the component's ngAfterViewInit timing.
  2. Call getDirections/getPanel/getRouteIndex only after the renderer exists — e.g. gate with a check that the component is bound (ComponentFactoryResolver/dynamic creation: use componentRef.instance after view init).
  3. Ensure the Google Maps JS API script has loaded (Loader ready promise or GOOGLE_MAPS_API_CONFIG script tag present) before rendering the component.
  4. If calling from a parent, put the call in ngAfterViewInit of the parent (not ngOnInit) or queue it via setTimeout/queueMicrotask after view init.
  5. Wrap interaction in try-catch as a defensive measure in dev builds since the throw is ngDevMode-gated.

Example fix

// before
ngOnInit() {
  this.renderer.getDirections({ origin: 'NYC', destination: 'Boston', travelMode: 'DRIVING' });
}
// after
ngAfterViewInit() {
  this.map.ready.subscribe(() => {
    this.renderer.getDirections({ origin: 'NYC', destination: 'Boston', travelMode: 'DRIVING' });
  });
}
Defensive patterns

Strategy: validation

Validate before calling

if (!rendererRef || !rendererRef.initialized) { /* defer or skip */ }

Type guard

function isRendererReady(r: MapDirectionsRenderer | undefined): r is MapDirectionsRenderer & { getDirections: NonNullable<MapDirectionsRenderer['getDirections']> } {
  return !!r;
}

Try / catch

try {
  renderer.getDirections(req);
} catch (e) {
  if ((e as Error).message.includes('Directions Renderer')) {
    // retry after map ready / queue the request
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling getDirections(), getPanel(), getRouteIndex(), or setting inputs that call _initialize before the component's ngAfterContentInit flow has created directionsRenderer — e.g. calling these methods in the parent's ngOnInit or immediately after creating the component dynamically.

Common situations: Querying directions in a constructor/ngOnInit, rendering the component behind *ngIf that flips without waiting for the map/library load, using @angular/google-maps without waiting for Google Maps API script load, dynamic component creation followed by immediate API calls.

Related errors


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