Skip to content

Commit

Permalink
fix(google-maps): handle trying to access the map before it has been …
Browse files Browse the repository at this point in the history
…initialized (#17805)

As things are set up at the moment, the Google `Map` object will be initialized once the API has loaded, however all of the methods on the `GoogleMap` component assume that the object will always be defined. This means that if any of the methods are called before it is initialized, we'll throw a null pointer error. These changes add a more readable error so people know what to do.
  • Loading branch information
crisbeto authored and jelbourn committed Nov 27, 2019
1 parent 61b423a commit d990243
Showing 1 changed file with 32 additions and 10 deletions.
42 changes: 32 additions & 10 deletions src/google-maps/google-map/google-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
@Output() zoomChanged = new EventEmitter<void>();

private _mapEl: HTMLElement;
_googleMap!: UpdatedGoogleMap;
_googleMap: UpdatedGoogleMap;

/** Whether we're currently rendering inside a browser. */
private _isBrowser: boolean;
Expand Down Expand Up @@ -244,8 +244,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
this._googleMapChanges = this._initializeMap(combinedOptionsChanges);
this._googleMapChanges.subscribe((googleMap: google.maps.Map) => {
this._googleMap = googleMap as UpdatedGoogleMap;

this._initializeEventHandlers();
this._initializeEventHandlers(this._googleMap);
});

this._watchForOptionsChanges();
Expand All @@ -267,6 +266,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
fitBounds(
bounds: google.maps.LatLngBounds|google.maps.LatLngBoundsLiteral,
padding?: number|google.maps.Padding) {
this._assertInitialized();
this._googleMap.fitBounds(bounds, padding);
}

Expand All @@ -275,6 +275,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.panBy
*/
panBy(x: number, y: number) {
this._assertInitialized();
this._googleMap.panBy(x, y);
}

Expand All @@ -283,6 +284,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.panTo
*/
panTo(latLng: google.maps.LatLng|google.maps.LatLngLiteral) {
this._assertInitialized();
this._googleMap.panTo(latLng);
}

Expand All @@ -293,6 +295,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
panToBounds(
latLngBounds: google.maps.LatLngBounds|google.maps.LatLngBoundsLiteral,
padding?: number|google.maps.Padding) {
this._assertInitialized();
this._googleMap.panToBounds(latLngBounds, padding);
}

Expand All @@ -301,6 +304,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getBounds
*/
getBounds(): google.maps.LatLngBounds|null {
this._assertInitialized();
return this._googleMap.getBounds() || null;
}

Expand All @@ -309,6 +313,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getCenter
*/
getCenter(): google.maps.LatLng {
this._assertInitialized();
return this._googleMap.getCenter();
}

Expand All @@ -317,6 +322,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getClickableIcons
*/
getClickableIcons(): boolean {
this._assertInitialized();
return this._googleMap.getClickableIcons();
}

Expand All @@ -325,6 +331,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getHeading
*/
getHeading(): number {
this._assertInitialized();
return this._googleMap.getHeading();
}

Expand All @@ -333,6 +340,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getMapTypeId
*/
getMapTypeId(): google.maps.MapTypeId|string {
this._assertInitialized();
return this._googleMap.getMapTypeId();
}

Expand All @@ -341,6 +349,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getProjection
*/
getProjection(): google.maps.Projection|null {
this._assertInitialized();
return this._googleMap.getProjection();
}

Expand All @@ -349,6 +358,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getStreetView
*/
getStreetView(): google.maps.StreetViewPanorama {
this._assertInitialized();
return this._googleMap.getStreetView();
}

Expand All @@ -357,6 +367,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getTilt
*/
getTilt(): number {
this._assertInitialized();
return this._googleMap.getTilt();
}

Expand All @@ -365,6 +376,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.getZoom
*/
getZoom(): number {
this._assertInitialized();
return this._googleMap.getZoom();
}

Expand All @@ -373,6 +385,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.controls
*/
get controls(): Array<google.maps.MVCArray<Node>> {
this._assertInitialized();
return this._googleMap.controls;
}

Expand All @@ -381,6 +394,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.data
*/
get data(): google.maps.Data {
this._assertInitialized();
return this._googleMap.data;
}

Expand All @@ -389,6 +403,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.mapTypes
*/
get mapTypes(): google.maps.MapTypeRegistry {
this._assertInitialized();
return this._googleMap.mapTypes;
}

Expand All @@ -397,6 +412,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
* https://developers.google.com/maps/documentation/javascript/reference/map#Map.overlayMapTypes
*/
get overlayMapTypes(): google.maps.MVCArray<google.maps.MapType> {
this._assertInitialized();
return this._googleMap.overlayMapTypes;
}

Expand All @@ -423,9 +439,8 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
private _initializeMap(optionsChanges: Observable<google.maps.MapOptions>):
Observable<google.maps.Map> {
return optionsChanges.pipe(
take(1), map(options => {
return new google.maps.Map(this._mapEl, options);
}),
take(1),
map(options => new google.maps.Map(this._mapEl, options)),
shareReplay(1));
}

Expand Down Expand Up @@ -457,7 +472,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
});
}

private _initializeEventHandlers() {
private _initializeEventHandlers(googleMap: UpdatedGoogleMap) {
// Ensure that we don't leak if called multiple times.
this._clearListeners();

Expand All @@ -484,7 +499,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
]);
eventHandlers.forEach((eventHandler: EventEmitter<void>, name: string) => {
if (eventHandler.observers.length > 0) {
this._listeners.push(this._googleMap.addListener(name, () => {
this._listeners.push(googleMap.addListener(name, () => {
eventHandler.emit();
}));
}
Expand All @@ -493,13 +508,13 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
(eventHandler: EventEmitter<google.maps.MouseEvent>, name: string) => {
if (eventHandler.observers.length > 0) {
this._listeners.push(
this._googleMap.addListener(name, (event: google.maps.MouseEvent) => {
googleMap.addListener(name, (event: google.maps.MouseEvent) => {
eventHandler.emit(event);
}));
}
});
if (this.mapClick.observers.length > 0) {
this._listeners.push(this._googleMap.addListener(
this._listeners.push(googleMap.addListener(
'click', (event: google.maps.MouseEvent|google.maps.IconMouseEvent) => {
this.mapClick.emit(event);
}));
Expand All @@ -514,4 +529,11 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {

this._listeners = [];
}

private _assertInitialized() {
if (!this._googleMap) {
throw Error('Cannot access Google Map information before the API has been initialized. ' +
'Please wait for the API to load before trying to interact with it.');
}
}
}

0 comments on commit d990243

Please sign in to comment.