Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loader reports warning when using importLibrary multiple times #809

Closed
usefulthink opened this issue Aug 18, 2023 · 9 comments · Fixed by #843 · May be fixed by #845
Closed

Loader reports warning when using importLibrary multiple times #809

usefulthink opened this issue Aug 18, 2023 · 9 comments · Fixed by #843 · May be fixed by #845
Labels
priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@usefulthink
Copy link
Contributor

usefulthink commented Aug 18, 2023

When loading the maps library followed by another library using loader.importLibrary() and async/await syntax, a misleading warning-message "Google Maps already loaded outside @googlemaps/js-api-loader.This may result in undesirable behavior as options and script parameters may not match." is written to the console.

Here's the code that triggers this behavior:

import Loader from '@googlemaps/js-api-loader';

async function main() {
  const loader = new Loader({apiKey: 'MY_API_KEY'});

  const {Map} = await loader.importLibrary('maps');
  
  // this line will trigger the warning message:
  await loader.importLibrary('marker');
}

The reason appears to be that the done flag isn't correctly set to true after the maps-api has initially been loaded.

@usefulthink usefulthink added triage me I really want to be triaged. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Aug 18, 2023
@hitarthdesai
Copy link

hitarthdesai commented Sep 5, 2023

Any updates on this issue, I have been facing the same issue for a while now.

Also, could be related to this:

seems like even if we specify a particular library name, it still returns the whole payload i.e. having the following

await loader.importLibrary('marker');

still loads and populates every library, as if we had called the deprecated .load() method.

@usefulthink usefulthink removed the triage me I really want to be triaged. label Sep 13, 2023
@venatiodecorus
Copy link

FWIW I found this example of loading multiple libraries here: https://cloud.google.com/blog/products/maps-platform/more-control-loading-maps-javascript-api

@explooosion
Copy link

Hi @usefulthink,

The assistance from @venatiodecorus was incredibly useful in this context.

Regarding the implementation, you can leverage Promise.all to efficiently load your libraries concurrently. Here's how you could do it:

const [mapLibrary, markerLibrary] = await Promise.all([
  loader.importLibrary('maps'),
  loader.importLibrary('marker')
]);

This code will allow you to import both maps and marker libraries in parallel, which can help streamline your setup process.

Best regards!

@wangela wangela added the priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. label Feb 15, 2024
@Profesor08
Copy link

This bug is related to this line https://github.com/googlemaps/js-api-loader/blob/main/src/index.ts#L630

Threre is no check if specific library is loaded, this check is uselles if libraries are imported one by one.

@owaisahmed5300
Copy link

Fix: Promise.all() instead await for every importLibrary.


import { Loader } from '@googlemaps/js-api-loader';

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

let libraries: any = null;

async function loadLibraries() {
  if (!libraries) {
    // not necessary to load all but just for an example.
    libraries = await Promise.all([
      loader.importLibrary('maps'),
      loader.importLibrary('places'),
      loader.importLibrary('marker'),
      loader.importLibrary('geocoding'),
    ]);
  }
  return libraries;
}

const [{ Map }, { Autocomplete }, { AdvancedMarkerElement }, { Geocoder }] = await loadLibraries();

export { Map, AdvancedMarkerElement, Geocoder, Autocomplete };

@chrisjshull
Copy link
Contributor

chrisjshull commented Apr 15, 2024

So this is an interesting race condition bug that I think only happens with two back-to-back await loader.importLibrary... calls.
Even putting an extra await 0; between the two calls resolves the issue. https://jsfiddle.net/b6vsx8dp/1/
(Not that I'd recommended this, just diagnosing.)

Though for what it's worth, even after this bug is fixed I would recommend using Promise.all() [edit: instead of back-to-back await loader.importLibrary...], as that allows the libraries to load in parallel.

@Profesor08
Copy link

Promise.all will not be helpful if you load libraries on need.

const { Map } = await loader.importLibrary("maps");

const showPlaces = async (places) => {
  const { Autocomplete } = await loader.importLibrary("places");

  // ...
};

@owaisahmed5300
Copy link

owaisahmed5300 commented Apr 15, 2024

@Profesor08 Yes, that's true.

You will need to call Promise.all() first and then access the variables later.

Something like this.

const [{ Map },{Autocomplete}] = await Promise.all([
  loader.importLibrary("maps"),
  loader.importLibrary("places")
]);
const showPlaces = async (places) => {
  // you can access `Autocomplete` variable here.
  // Also you can access them using google.maps.places.Autocomplete
};

@owaisahmed5300
Copy link

owaisahmed5300 commented Apr 15, 2024

Maybe in future we could pass an array of Libraries instead 1 library in importLibrary(), but for now use Promise.all().

You can use Promise.all() in your main.js file and in other files you can access the map Libraries normally as you do using google.maps.

Or if using react then you can simply define them in a Context and share the libraries as props to nested components.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
8 participants