angular/components · error

Cannot interact with a Google Map Traffic Layer before it ha

Error message

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

What it means

MapTrafficLayer throws this from _assertInitialized when code touches the layer before the internal google.maps.TrafficLayer instance has been created. The instance is created asynchronously once the Maps JS API resolves. Unlike some sibling components this guard is not wrapped in an ngDevMode check, so it throws in production too.

Source

Thrown at src/google-maps/map-traffic-layer/map-traffic-layer.ts:118

      map(autoRefresh => {
        const combinedOptions: google.maps.TrafficLayerOptions = {autoRefresh};
        return combinedOptions;
      }),
    );
  }

  private _watchForAutoRefreshChanges() {
    this._combineOptions()
      .pipe(takeUntil(this._destroyed))
      .subscribe(options => {
        this._assertInitialized();
        this.trafficLayer.setOptions(options);
      });
  }

  private _assertInitialized(): asserts this is {trafficLayer: google.maps.TrafficLayer} {
    if (!this.trafficLayer) {
      throw Error(
        'Cannot interact with a Google Map Traffic Layer before it has been initialized. ' +
          'Please wait for the Traffic Layer to load before trying to interact with it.',
      );
    }
  }
}

View on GitHub (pinned to 0411926e7d)

Solutions

  1. Defer interaction until the Maps API has loaded — use the map's mapReady output or the GoogleMapsModule's loaded promise pattern.
  2. Check that the Maps loader succeeded (API key valid, script not blocked); a failed load leaves trafficLayer undefined forever.
  3. Move option-setting code into a callback that runs after map initialization instead of ngOnInit.
  4. Guard calls: only invoke when the layer reports it is initialized.

Example fix

// before
ngOnInit() {
  this.trafficLayer.setOptions({}); // throws before load
}
// after
this.map.mapReady.subscribe(() => {
  this.trafficLayer.setOptions({});
});
Defensive patterns

Strategy: type-guard

Validate before calling

if (layer && (layer as any).trafficLayer) { layer.setOptions({...}); }

Type guard

function isTrafficLayerInitialized(l: any): l is {trafficLayer: google.maps.TrafficLayer} {
  return !!l && !!l.trafficLayer;
}

Try / catch

try {
  this.trafficLayerDirective.setOptions(options);
} catch (e) {
  if ((e as Error).message.includes('Traffic Layer')) {
    this.map.mapReady.pipe(take(1)).subscribe(() => this.trafficLayerDirective.setOptions(options));
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling setOptions/autoRefresh-related public methods or _initialize/_watchForAutoRefreshChanges paths before this.trafficLayer is assigned — typically calling a method on the MapTrafficLayer directive immediately after construction or before the Maps API finishes loading.

Common situations: Toggling traffic layer options during initial page load before mapReady; the Maps script failing to load (bad key, network block) so the layer is never created; calling via template ref in ngOnInit.

Related errors


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