diff --git a/src/components/__tests__/api-provider.test.tsx b/src/components/__tests__/api-provider.test.tsx index eb913ffd..239827e3 100644 --- a/src/components/__tests__/api-provider.test.tsx +++ b/src/components/__tests__/api-provider.test.tsx @@ -295,6 +295,26 @@ test('waits for externally installed importLibrary before marking API as loaded' expect(settingsInstance.fetchAppCheckToken).toBe(mockFetchToken); }); +test('primes js-api-loader when importLibrary is installed externally', async () => { + google.maps.importLibrary = asGoogleMapsImportLibrary(async libraryName => { + await importLibraryPromise; + + if (libraryName === 'core') { + return {} as google.maps.CoreLibrary; + } + + return {} as google.maps.MapsLibrary; + }); + + render(); + + await act(async () => { + triggerMapsApiLoaded(); + }); + + await waitFor(() => expect(setOptionsSpy).toHaveBeenCalled()); +}); + describe('internalUsageAttributionIds', () => { test('provides default attribution IDs in context', () => { render( diff --git a/src/components/api-provider.tsx b/src/components/api-provider.tsx index cc88ff7b..edc39556 100644 --- a/src/components/api-provider.tsx +++ b/src/components/api-provider.tsx @@ -291,30 +291,6 @@ function useGoogleMapsApiLoader(props: APIProviderProps) { const librariesToLoad = ['core', 'maps', ...libraries]; - // If the google.maps namespace is already available, the API has been loaded externally. - if (window.google?.maps?.importLibrary as unknown) { - await Promise.all( - librariesToLoad.map(name => importLibraryCallback(name)) - ); - if (!serializedApiParams) { - updateLoadingStatus(APILoadingStatus.LOADED); - } - if (onLoad) onLoad(); - return; - } - - // Abort if the API is already loading or has been loaded. - if ( - loadingStatus === APILoadingStatus.LOADING || - loadingStatus === APILoadingStatus.LOADED - ) { - if (loadingStatus === APILoadingStatus.LOADED && onLoad) onLoad(); - return; - } - - serializedApiParams = currentSerializedParams; - updateLoadingStatus(APILoadingStatus.LOADING); - const options: APIOptions = Object.fromEntries( Object.entries({ key: apiKey, @@ -338,6 +314,37 @@ function useGoogleMapsApiLoader(props: APIProviderProps) { options.solutionChannel = solutionChannel; } + // If the google.maps namespace is already available, the API has been loaded externally. + if (window.google?.maps?.importLibrary as unknown) { + const shouldUpdateLoadingStatus = !serializedApiParams; + + if (shouldUpdateLoadingStatus) { + serializedApiParams = currentSerializedParams; + setOptions(options); + } + + await Promise.all( + librariesToLoad.map(name => importLibraryCallback(name)) + ); + if (shouldUpdateLoadingStatus) { + updateLoadingStatus(APILoadingStatus.LOADED); + } + if (onLoad) onLoad(); + return; + } + + // Abort if the API is already loading or has been loaded. + if ( + loadingStatus === APILoadingStatus.LOADING || + loadingStatus === APILoadingStatus.LOADED + ) { + if (loadingStatus === APILoadingStatus.LOADED && onLoad) onLoad(); + return; + } + + serializedApiParams = currentSerializedParams; + updateLoadingStatus(APILoadingStatus.LOADING); + // this will actually trigger loading the maps API setOptions(options);