js-api-loader icon indicating copy to clipboard operation
js-api-loader copied to clipboard

Maps: @googlemaps/js-api-loader importLibrary fails sometimes even after multiple tries.

Open grusingh opened this issue 1 year ago • 3 comments

I am using the @googlemaps/js-api-loader package in a React app. I am noticing that for some users the map libraries fail to load even after multiple retries.

Code:

import React, {createContext, useContext, useEffect, useState} from 'react';
import {Loader} from '@googlemaps/js-api-loader';

const GoogleMapsContext = createContext({
    googleMapsLoaded: false,
    googleMapsLibraries: null,
});

const MAX_RETRIES = 3; 

const loadLibraries = (loader, retries = MAX_RETRIES) => {
    return Promise.allSettled([
        loader.importLibrary('core'),
        loader.importLibrary('maps'),
        loader.importLibrary('marker'),
        loader.importLibrary('streetView'),
        loader.importLibrary('geocoding'),
        loader.importLibrary('places'),
        loader.importLibrary('routes'),
    ]).then(results => {
        const loadedLibraries = results
            .filter(result => result.status === 'fulfilled')
            .map(result => (result as PromiseFulfilledResult<any>).value);
        const failedLibraries = results.filter(
            result => result.status === 'rejected'
        );

        if (failedLibraries.length > 0) {
            if (retries === 0) {
                throw new Error(
                    `Failed to load ${failedLibraries.length} libraries after ${MAX_RETRIES} attempts.`
                );
            } else {
                return loadLibraries(loader, retries - 1);
            }
        }

        return loadedLibraries;
    });
};

const GoogleMapsProvider = ({apiKey, children}) => {
    const [googleMapsLoaded, setGoogleMapsLoaded] = useState(false);
    const [googleMapsLibraries, setGoogleMapsLibraries] = useState(null);

    useEffect(() => {
        let isCancelled = false;

        const loader = new Loader({
            apiKey,
            version: 'weekly',
        });

        loadLibraries(loader)
            .then(libs => {
                if (!isCancelled) {
                    setGoogleMapsLibraries({
                        core: libs[0],
                        maps: libs[1],
                        marker: libs[2],
                        streetView: libs[3],
                        geocoding: libs[4],
                        places: libs[5],
                        routes: libs[6],
                    });
                    setGoogleMapsLoaded(true);
                }
            })
            .catch(error => {
                console.error({
                    error,
                    message: 'GoogleMapsProvider: Error loading Google Maps libraries',
                });
            });

        return () => {
            isCancelled = true;
        };
    }, [apiKey]);

    if (typeof window === 'undefined') {
        return children;
    }

    return (
        <GoogleMapsContext.Provider
            value={{
                googleMapsLoaded,
                googleMapsLibraries,
            }}
        >
            {children}
        </GoogleMapsContext.Provider>
    );
};

const useGoogleMapsLibraries = () => {
    return useContext(GoogleMapsContext);
};

export {GoogleMapsProvider, useGoogleMapsLibraries};

grusingh avatar Mar 04 '24 20:03 grusingh

If you would like to upvote the priority of this issue, please comment below or react on the original post above with :+1: so we can see what is popular when we triage.

@grusingh Thank you for opening this issue. 🙏 Please check out these other resources that might help you get to a resolution in the meantime:

This is an automated message, feel free to ignore.

wangela avatar Mar 04 '24 20:03 wangela

Hello, i have the same issue with my users but only on Firefox. The error is random, it does not affect all users on Firefox and i cannot reproduce every time. Im using the library on a Vue3/Vite/PWA project.

awcs avatar Mar 08 '24 09:03 awcs

for some users the map libraries fail to load even after multiple retries.

What does "fail to load" mean in this case? Is the exception being thrown?
Is this affecting all libraries or just some of them? Are there any warnings or errors logged in the console when this happens?

As far as I can tell, the promise returned by loader.importLibrary() will only be rejected if the underlying google.maps.importLibrary-call rejects. Under which circumstances that might happen is not documented.

usefulthink avatar Oct 10 '24 16:10 usefulthink