Skip to content

Commit

Permalink
fix(google-maps): error if API is initialized incorrectly (#26520)
Browse files Browse the repository at this point in the history
When the Google Maps API fails to initialize (e.g. when the API key is invalid), it returns dummy objects which return `undefined` from `addListener`, causing an error when the `MapEventManager` is destroyed.

These changes add a check to guard against those errors.

Fixes #26514.

(cherry picked from commit 1564880)
  • Loading branch information
crisbeto committed Jan 28, 2023
1 parent 86db7b7 commit e48a5af
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
14 changes: 14 additions & 0 deletions src/google-maps/map-event-manager.spec.ts
Expand Up @@ -141,6 +141,20 @@ describe('MapEventManager', () => {
alternateTarget.triggerListeners('click');
expect(spy).toHaveBeenCalledTimes(2);
});

it('should not throw with an invalid target', () => {
manager.setTarget({
addListener: () => undefined,
});
const stream = manager.getLazyEmitter('click');
const completeSpy = jasmine.createSpy('completeSpy');
const errorSpy = jasmine.createSpy('errorSpy');
stream.subscribe({complete: completeSpy, error: errorSpy});

expect(() => manager.destroy()).not.toThrow();
expect(completeSpy).toHaveBeenCalled();
expect(errorSpy).not.toHaveBeenCalled();
});
});

/** Imitates a Google Maps event target and keeps track of the registered events. */
Expand Down
10 changes: 9 additions & 1 deletion src/google-maps/map-event-manager.ts
Expand Up @@ -15,7 +15,7 @@ type MapEventManagerTarget =
addListener: (
name: string,
callback: (...args: any[]) => void,
) => google.maps.MapsEventListener;
) => google.maps.MapsEventListener | undefined;
}
| undefined;

Expand Down Expand Up @@ -51,6 +51,14 @@ export class MapEventManager {
const listener = target.addListener(name, (event: T) => {
this._ngZone.run(() => observer.next(event));
});

// If there's an error when initializing the Maps API (e.g. a wrong API key), it will
// return a dummy object that returns `undefined` from `addListener` (see #26514).
if (!listener) {
observer.complete();
return undefined;
}

this._listeners.push(listener);
return () => listener.remove();
});
Expand Down

0 comments on commit e48a5af

Please sign in to comment.