From 278fbeb665121335d7ab7c2f2f2fdb837ffff6dc Mon Sep 17 00:00:00 2001 From: Kristiyan Kostadinov Date: Tue, 9 Mar 2021 17:56:11 +0100 Subject: [PATCH] fix(google-maps): instantiate geocoder lazily Currently we instantiate the `Geocoder` when the `MapGeocoder` provider is instantiated which may be too early if the Google Maps API is loaded lazily. These changes switch to creating it only when `geocode` is called. Fixes #22148. --- src/google-maps/map-geocoder/map-geocoder.spec.ts | 7 ++++++- src/google-maps/map-geocoder/map-geocoder.ts | 12 ++++++++---- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/google-maps/map-geocoder/map-geocoder.spec.ts b/src/google-maps/map-geocoder/map-geocoder.spec.ts index 80aebfc1f953..af8bbd9510f0 100644 --- a/src/google-maps/map-geocoder/map-geocoder.spec.ts +++ b/src/google-maps/map-geocoder/map-geocoder.spec.ts @@ -22,7 +22,12 @@ describe('MapGeocoder', () => { (window.google as any) = undefined; }); - it('initializes the Google Maps Geocoder', () => { + it('does not initialize the Google Maps Geocoder immediately', () => { + expect(geocoderConstructorSpy).not.toHaveBeenCalled(); + }); + + it('initializes the Google Maps Geocoder after `geocode` is called', () => { + geocoder.geocode({}).subscribe(); expect(geocoderConstructorSpy).toHaveBeenCalled(); }); diff --git a/src/google-maps/map-geocoder/map-geocoder.ts b/src/google-maps/map-geocoder/map-geocoder.ts index 3a18fd9d9d51..843ab77109f6 100644 --- a/src/google-maps/map-geocoder/map-geocoder.ts +++ b/src/google-maps/map-geocoder/map-geocoder.ts @@ -23,17 +23,21 @@ export interface MapGeocoderResponse { */ @Injectable({providedIn: 'root'}) export class MapGeocoder { - private readonly _geocoder: google.maps.Geocoder; + private _geocoder: google.maps.Geocoder|undefined; - constructor(private readonly _ngZone: NgZone) { - this._geocoder = new google.maps.Geocoder(); - } + constructor(private readonly _ngZone: NgZone) {} /** * See developers.google.com/maps/documentation/javascript/reference/geocoder#Geocoder.geocode */ geocode(request: google.maps.GeocoderRequest): Observable { return new Observable(observer => { + // Initialize the `Geocoder` lazily since the Google Maps API may + // not have been loaded when the provider is instantiated. + if (!this._geocoder) { + this._geocoder = new google.maps.Geocoder(); + } + this._geocoder.geocode(request, (results, status) => { this._ngZone.run(() => { observer.next({results, status});