@@ -38,6 +38,11 @@ type MapOptions = Pick<
3838
3939let _google : typeof google ;
4040
41+ // Loading the Google Maps API is an asynchronous operation, so we need to track the loading state to prevent race conditions.
42+ let _loading = false ;
43+ let _loaded = false ;
44+ let _onLoadedCallbacks : Array < ( ) => void > = [ ] ;
45+
4146const parser = new DOMParser ( ) ;
4247
4348export default class extends AbstractMapController <
@@ -64,39 +69,51 @@ export default class extends AbstractMapController<
6469 public parser : DOMParser ;
6570
6671 async connect ( ) {
67- if ( ! _google ) {
68- _google = { maps : { } as typeof google . maps } ;
69-
70- let { libraries = [ ] , ...loaderOptions } = this . providerOptionsValue ;
71-
72- const loader = new Loader ( loaderOptions ) ;
73-
74- // We could have used `loader.load()` to correctly load libraries, but this method is deprecated in favor of `loader.importLibrary()`.
75- // But `loader.importLibrary()` is not a 1-1 replacement for `loader.load()`, we need to re-build the `google.maps` object ourselves,
76- // see https://github.com/googlemaps/js-api-loader/issues/837 for more information.
77- libraries = [ 'core' , ...libraries . filter ( ( library ) => library !== 'core' ) ] ; // Ensure 'core' is loaded first
78- const librariesImplementations = await Promise . all (
79- libraries . map ( ( library ) => loader . importLibrary ( library ) )
80- ) ;
81- librariesImplementations . map ( ( libraryImplementation , index ) => {
82- if ( typeof libraryImplementation !== 'object' || libraryImplementation === null ) {
83- return ;
84- }
72+ const onLoaded = ( ) => super . connect ( ) ;
8573
86- const library = libraries [ index ] ;
74+ if ( _loaded ) {
75+ onLoaded ( ) ;
76+ return ;
77+ }
8778
88- // The following libraries are in a sub-namespace
89- if ( [ 'marker' , 'places' , 'geometry' , 'journeySharing' , 'drawing' , 'visualization' ] . includes ( library ) ) {
90- // @ts -ignore
91- _google . maps [ library ] = libraryImplementation as any ;
92- } else {
93- _google . maps = { ..._google . maps , ...libraryImplementation } ;
94- }
95- } ) ;
79+ if ( _loading ) {
80+ _onLoadedCallbacks . push ( onLoaded ) ;
81+ return ;
9682 }
9783
98- super . connect ( ) ;
99- this . parser = new DOMParser ( ) ;
84+ _loading = true ;
85+ _google = { maps : { } as typeof google . maps } ;
86+
87+ let { libraries = [ ] , ...loaderOptions } = this . providerOptionsValue ;
88+
89+ const loader = new Loader ( loaderOptions ) ;
90+
91+ // We could have used `loader.load()` to correctly load libraries, but this method is deprecated in favor of `loader.importLibrary()`.
92+ // But `loader.importLibrary()` is not a 1-1 replacement for `loader.load()`, we need to re-build the `google.maps` object ourselves,
93+ // see https://github.com/googlemaps/js-api-loader/issues/837 for more information.
94+ libraries = [ 'core' , ...libraries . filter ( ( library ) => library !== 'core' ) ] ; // Ensure 'core' is loaded first
95+ const librariesImplementations = await Promise . all ( libraries . map ( ( library ) => loader . importLibrary ( library ) ) ) ;
96+ librariesImplementations . map ( ( libraryImplementation , index ) => {
97+ if ( typeof libraryImplementation !== 'object' || libraryImplementation === null ) {
98+ return ;
99+ }
100+
101+ const library = libraries [ index ] ;
102+
103+ // The following libraries are in a sub-namespace
104+ if ( [ 'marker' , 'places' , 'geometry' , 'journeySharing' , 'drawing' , 'visualization' ] . includes ( library ) ) {
105+ // @ts -ignore
106+ _google . maps [ library ] = libraryImplementation as any ;
107+ } else {
108+ _google . maps = { ..._google . maps , ...libraryImplementation } ;
109+ }
110+ } ) ;
111+
112+ _loading = false ;
113+ _loaded = true ;
114+ onLoaded ( ) ;
115+ _onLoadedCallbacks . forEach ( ( callback ) => callback ( ) ) ;
116+ _onLoadedCallbacks = [ ] ;
100117 }
101118
102119 public centerValueChanged ( ) : void {
0 commit comments