diff --git a/src/google-maps/google-map/google-map.ts b/src/google-maps/google-map/google-map.ts index d2cf0800a0a5..73ecd63e45be 100644 --- a/src/google-maps/google-map/google-map.ts +++ b/src/google-maps/google-map/google-map.ts @@ -30,6 +30,7 @@ import {isPlatformBrowser} from '@angular/common'; import {Observable} from 'rxjs'; import {MapEventManager} from '../map-event-manager'; import {take} from 'rxjs/operators'; +import {importLibrary} from '../import-library'; interface GoogleMapsWindow extends Window { gm_authFailure?: () => void; @@ -310,8 +311,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy { // user has subscribed to. this._ngZone.runOutsideAngular(async () => { const mapConstructor = - google.maps.Map || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).Map; + google.maps.Map || (await importLibrary('maps', 'Map')); this.googleMap = new mapConstructor(this._mapEl, this._combineOptions()); this._eventManager.setTarget(this.googleMap); this.mapInitialized.emit(this.googleMap); diff --git a/src/google-maps/import-library.ts b/src/google-maps/import-library.ts new file mode 100644 index 000000000000..00075292241e --- /dev/null +++ b/src/google-maps/import-library.ts @@ -0,0 +1,15 @@ +/** + * @license + * Copyright Google LLC All Rights Reserved. + * + * Use of this source code is governed by an MIT-style license that can be + * found in the LICENSE file at https://angular.io/license + */ + +/** Imports a Google Maps library. */ +export async function importLibrary(name: string, symbol: string): Promise { + // TODO(crisbeto): needs to cast to `any` to avoid some internal limitations around typings. + // Should be cleaned up eventually. + const library = await (window as any).google.maps.importLibrary(name); + return library[symbol]; +} diff --git a/src/google-maps/map-bicycling-layer/map-bicycling-layer.ts b/src/google-maps/map-bicycling-layer/map-bicycling-layer.ts index 9935e2c94b4f..720a009ce8c9 100644 --- a/src/google-maps/map-bicycling-layer/map-bicycling-layer.ts +++ b/src/google-maps/map-bicycling-layer/map-bicycling-layer.ts @@ -12,6 +12,7 @@ import {Directive, EventEmitter, Output} from '@angular/core'; import {MapBaseLayer} from '../map-base-layer'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Bicycling Layer via the Google Maps JavaScript API. @@ -38,7 +39,7 @@ export class MapBicyclingLayer extends MapBaseLayer { protected override async _initializeObject() { const layerConstructor = google.maps.BicyclingLayer || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).BicyclingLayer; + (await importLibrary('maps', 'BicyclingLayer')); this.bicyclingLayer = new layerConstructor(); this.bicyclingLayerInitialized.emit(this.bicyclingLayer); } diff --git a/src/google-maps/map-circle/map-circle.ts b/src/google-maps/map-circle/map-circle.ts index f42766af0d43..a6b5912793a1 100644 --- a/src/google-maps/map-circle/map-circle.ts +++ b/src/google-maps/map-circle/map-circle.ts @@ -24,6 +24,7 @@ import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Circle via the Google Maps JavaScript API. @@ -180,8 +181,7 @@ export class MapCircle implements OnInit, OnDestroy { this._ngZone.runOutsideAngular(async () => { const map = await this._map._resolveMap(); const circleConstructor = - google.maps.Circle || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).Circle; + google.maps.Circle || (await importLibrary('maps', 'Circle')); this.circle = new circleConstructor(options); this._assertInitialized(); this.circle.setMap(map); diff --git a/src/google-maps/map-directions-renderer/map-directions-renderer.ts b/src/google-maps/map-directions-renderer/map-directions-renderer.ts index 8c28b42b4f32..b207f5580fa9 100644 --- a/src/google-maps/map-directions-renderer/map-directions-renderer.ts +++ b/src/google-maps/map-directions-renderer/map-directions-renderer.ts @@ -24,6 +24,7 @@ import { import {Observable} from 'rxjs'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Directions Renderer via the Google Maps @@ -88,8 +89,7 @@ export class MapDirectionsRenderer implements OnInit, OnChanges, OnDestroy { const map = await this._googleMap._resolveMap(); const rendererConstructor = google.maps.DirectionsRenderer || - ((await google.maps.importLibrary('routes')) as google.maps.RoutesLibrary) - .DirectionsRenderer; + (await importLibrary('routes', 'DirectionsRenderer')); this.directionsRenderer = new rendererConstructor(this._combineOptions()); this._assertInitialized(); this.directionsRenderer.setMap(map); diff --git a/src/google-maps/map-directions-renderer/map-directions-service.ts b/src/google-maps/map-directions-renderer/map-directions-service.ts index 4bff705cf2c5..c4c7a7473a86 100644 --- a/src/google-maps/map-directions-renderer/map-directions-service.ts +++ b/src/google-maps/map-directions-renderer/map-directions-service.ts @@ -10,6 +10,7 @@ /// import {Injectable, NgZone} from '@angular/core'; +import {importLibrary} from '../import-library'; import {Observable} from 'rxjs'; export interface MapDirectionsResponse { @@ -51,8 +52,7 @@ export class MapDirectionsService { if (!this._directionsService) { const serviceConstructor = google.maps.DirectionsService || - ((await google.maps.importLibrary('routes')) as google.maps.RoutesLibrary) - .DirectionsService; + (await importLibrary('routes', 'DirectionsService')); this._directionsService = new serviceConstructor(); } diff --git a/src/google-maps/map-geocoder/map-geocoder.ts b/src/google-maps/map-geocoder/map-geocoder.ts index 87a1fc94b4e5..859c0f30f4d5 100644 --- a/src/google-maps/map-geocoder/map-geocoder.ts +++ b/src/google-maps/map-geocoder/map-geocoder.ts @@ -10,6 +10,7 @@ /// import {Injectable, NgZone} from '@angular/core'; +import {importLibrary} from '../import-library'; import {Observable} from 'rxjs'; export interface MapGeocoderResponse { @@ -47,7 +48,7 @@ export class MapGeocoder { if (!this._geocoder) { const geocoderConstructor = google.maps.Geocoder || - ((await google.maps.importLibrary('geocoding')) as google.maps.GeocodingLibrary).Geocoder; + (await importLibrary('geocoding', 'Geocoder')); this._geocoder = new geocoderConstructor(); } diff --git a/src/google-maps/map-ground-overlay/map-ground-overlay.ts b/src/google-maps/map-ground-overlay/map-ground-overlay.ts index 5c5e2170b91e..619c117e828f 100644 --- a/src/google-maps/map-ground-overlay/map-ground-overlay.ts +++ b/src/google-maps/map-ground-overlay/map-ground-overlay.ts @@ -24,6 +24,7 @@ import {takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Ground Overlay via the Google Maps JavaScript API. @@ -123,7 +124,7 @@ export class MapGroundOverlay implements OnInit, OnDestroy { const map = await this._map._resolveMap(); const overlayConstructor = google.maps.GroundOverlay || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).GroundOverlay; + (await importLibrary('maps', 'GroundOverlay')); this.groundOverlay = new overlayConstructor(this._url.getValue(), bounds, { clickable: this.clickable, opacity: this._opacity.value, diff --git a/src/google-maps/map-heatmap-layer/map-heatmap-layer.ts b/src/google-maps/map-heatmap-layer/map-heatmap-layer.ts index a2647399a0a7..b2e387cf3500 100644 --- a/src/google-maps/map-heatmap-layer/map-heatmap-layer.ts +++ b/src/google-maps/map-heatmap-layer/map-heatmap-layer.ts @@ -22,6 +22,7 @@ import { } from '@angular/core'; import {GoogleMap} from '../google-map/google-map'; +import {importLibrary} from '../import-library'; /** Possible data that can be shown on a heatmap layer. */ export type HeatmapData = @@ -81,7 +82,7 @@ export class MapHeatmapLayer implements OnInit, OnChanges, OnDestroy { if (this._googleMap._isBrowser) { if ( !window.google?.maps?.visualization && - !window.google?.maps.importLibrary && + !(window as any).google?.maps.importLibrary && (typeof ngDevMode === 'undefined' || ngDevMode) ) { throw Error( @@ -98,8 +99,10 @@ export class MapHeatmapLayer implements OnInit, OnChanges, OnDestroy { const map = await this._googleMap._resolveMap(); const heatmapConstructor = google.maps.visualization?.HeatmapLayer || - ((await google.maps.importLibrary('visualization')) as google.maps.VisualizationLibrary) - .HeatmapLayer; + (await importLibrary( + 'visualization', + 'HeatmapLayer', + )); this.heatmap = new heatmapConstructor(this._combineOptions()); this._assertInitialized(); this.heatmap.setMap(map); diff --git a/src/google-maps/map-info-window/map-info-window.ts b/src/google-maps/map-info-window/map-info-window.ts index eb7c00019348..614b171b109e 100644 --- a/src/google-maps/map-info-window/map-info-window.ts +++ b/src/google-maps/map-info-window/map-info-window.ts @@ -26,6 +26,7 @@ import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; import {MapAnchorPoint} from '../map-anchor-point'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps info window via the Google Maps JavaScript API. @@ -122,7 +123,7 @@ export class MapInfoWindow implements OnInit, OnDestroy { this._ngZone.runOutsideAngular(async () => { const infoWindowConstructor = google.maps.InfoWindow || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).InfoWindow; + (await importLibrary('maps', 'InfoWindow')); this.infoWindow = new infoWindowConstructor(options); this._eventManager.setTarget(this.infoWindow); this.infoWindowInitialized.emit(this.infoWindow); diff --git a/src/google-maps/map-kml-layer/map-kml-layer.ts b/src/google-maps/map-kml-layer/map-kml-layer.ts index 785293d9f58b..358f07d240a3 100644 --- a/src/google-maps/map-kml-layer/map-kml-layer.ts +++ b/src/google-maps/map-kml-layer/map-kml-layer.ts @@ -24,6 +24,7 @@ import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps KML Layer via the Google Maps JavaScript API. @@ -100,7 +101,7 @@ export class MapKmlLayer implements OnInit, OnDestroy { const map = await this._map._resolveMap(); const layerConstructor = google.maps.KmlLayer || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).KmlLayer; + (await importLibrary('maps', 'KmlLayer')); this.kmlLayer = new layerConstructor(options); this._assertInitialized(); this.kmlLayer.setMap(map); diff --git a/src/google-maps/map-marker/map-marker.ts b/src/google-maps/map-marker/map-marker.ts index 347f5b18d6af..85989b3f506a 100644 --- a/src/google-maps/map-marker/map-marker.ts +++ b/src/google-maps/map-marker/map-marker.ts @@ -27,6 +27,7 @@ import {take} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; import {MapAnchorPoint} from '../map-anchor-point'; +import {importLibrary} from '../import-library'; /** * Default options for the Google Maps marker component. Displays a marker @@ -293,8 +294,7 @@ export class MapMarker implements OnInit, OnChanges, OnDestroy, MapAnchorPoint { this._ngZone.runOutsideAngular(async () => { const map = await this._googleMap._resolveMap(); const markerConstructor = - google.maps.Marker || - ((await google.maps.importLibrary('marker')) as google.maps.MarkerLibrary).Marker; + google.maps.Marker || (await importLibrary('marker', 'Marker')); this.marker = new markerConstructor(this._combineOptions()); this._assertInitialized(); diff --git a/src/google-maps/map-polygon/map-polygon.ts b/src/google-maps/map-polygon/map-polygon.ts index 4e7be956760d..9a3e3204d765 100644 --- a/src/google-maps/map-polygon/map-polygon.ts +++ b/src/google-maps/map-polygon/map-polygon.ts @@ -24,6 +24,7 @@ import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Polygon via the Google Maps JavaScript API. @@ -157,8 +158,7 @@ export class MapPolygon implements OnInit, OnDestroy { this._ngZone.runOutsideAngular(async () => { const map = await this._map._resolveMap(); const polygonConstructor = - google.maps.Polygon || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).Polygon; + google.maps.Polygon || (await importLibrary('maps', 'Polygon')); this.polygon = new polygonConstructor(options); this._assertInitialized(); this.polygon.setMap(map); diff --git a/src/google-maps/map-polyline/map-polyline.ts b/src/google-maps/map-polyline/map-polyline.ts index efa168a1dc21..beb7d5aa6093 100644 --- a/src/google-maps/map-polyline/map-polyline.ts +++ b/src/google-maps/map-polyline/map-polyline.ts @@ -24,6 +24,7 @@ import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Polyline via the Google Maps JavaScript API. @@ -156,7 +157,7 @@ export class MapPolyline implements OnInit, OnDestroy { const map = await this._map._resolveMap(); const polylineConstructor = google.maps.Polyline || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).Polyline; + (await importLibrary('maps', 'Polyline')); this.polyline = new polylineConstructor(options); this._assertInitialized(); this.polyline.setMap(map); diff --git a/src/google-maps/map-rectangle/map-rectangle.ts b/src/google-maps/map-rectangle/map-rectangle.ts index 6adff31cec33..50987febfd33 100644 --- a/src/google-maps/map-rectangle/map-rectangle.ts +++ b/src/google-maps/map-rectangle/map-rectangle.ts @@ -24,6 +24,7 @@ import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; import {MapEventManager} from '../map-event-manager'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Rectangle via the Google Maps JavaScript API. @@ -165,7 +166,7 @@ export class MapRectangle implements OnInit, OnDestroy { const map = await this._map._resolveMap(); const rectangleConstructor = google.maps.Rectangle || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).Rectangle; + (await importLibrary('maps', 'Rectangle')); this.rectangle = new rectangleConstructor(options); this._assertInitialized(); this.rectangle.setMap(map); diff --git a/src/google-maps/map-traffic-layer/map-traffic-layer.ts b/src/google-maps/map-traffic-layer/map-traffic-layer.ts index e70818e83831..bb4700cc0b6b 100644 --- a/src/google-maps/map-traffic-layer/map-traffic-layer.ts +++ b/src/google-maps/map-traffic-layer/map-traffic-layer.ts @@ -14,6 +14,7 @@ import {BehaviorSubject, Observable, Subject} from 'rxjs'; import {map, take, takeUntil} from 'rxjs/operators'; import {GoogleMap} from '../google-map/google-map'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Traffic Layer via the Google Maps JavaScript API. @@ -62,7 +63,7 @@ export class MapTrafficLayer implements OnInit, OnDestroy { const map = await this._map._resolveMap(); const layerConstructor = google.maps.TrafficLayer || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).TrafficLayer; + (await importLibrary('maps', 'TrafficLayer')); this.trafficLayer = new layerConstructor(options); this._assertInitialized(); this.trafficLayer.setMap(map); diff --git a/src/google-maps/map-transit-layer/map-transit-layer.ts b/src/google-maps/map-transit-layer/map-transit-layer.ts index d0a3812e8840..4f1d62ca8e6c 100644 --- a/src/google-maps/map-transit-layer/map-transit-layer.ts +++ b/src/google-maps/map-transit-layer/map-transit-layer.ts @@ -12,6 +12,7 @@ import {Directive, EventEmitter, Output} from '@angular/core'; import {MapBaseLayer} from '../map-base-layer'; +import {importLibrary} from '../import-library'; /** * Angular component that renders a Google Maps Transit Layer via the Google Maps JavaScript API. @@ -38,7 +39,7 @@ export class MapTransitLayer extends MapBaseLayer { protected override async _initializeObject() { const layerConstructor = google.maps.TransitLayer || - ((await google.maps.importLibrary('maps')) as google.maps.MapsLibrary).TransitLayer; + (await importLibrary('maps', 'TransitLayer')); this.transitLayer = new layerConstructor(); this.transitLayerInitialized.emit(this.transitLayer); }