esbanarango / ember-place-autocomplete

Ember cli addon to provide a component that uses Google Places API to autocomplete place information when people write their address
MIT License
63 stars 62 forks source link

Application initializes before Google Places library loads #146

Open veelci opened 1 year ago

veelci commented 1 year ago

Description

I'm running into an issue where my very small application loads and initializes before the Google Places library loads.

This is problematic because "window.google" is not defined when the google and navigator instance initializers execute due to the places library being loaded asynchronously. This causes the GooglePlaceAutocomplete component to fail initialization.

It looks like the addon used to read "window.google" directly, which would have been fine.

This occurs in both Ember 3.28.6 and 4.12.2, with the following versions of this addon: v2.1.2, master, and the "Upgraded to Ember 4.12" pull request.

veelci commented 1 year ago

For those of you encountering the same issue, I've worked around the issue by creating an initializer that defers application readiness until the places library loads.

import { later } from '@ember/runloop';

/**
 * Forces the application to wait until Google Places initializes.
 *
 * This is necessary because ember-place-autocomplete loads the places library asynchronously.
 * While usually fine, this application is very small and tends to complete initialization before the
 * Google Places library loads.
 */
export function initialize(application) {
  application.deferReadiness();

  const maxWaitTime = 5000;
  const waitInterval = 500;
  const start = new Date().getTime();

  const waitUntilLoad = () => {
    const currentWait = new Date().getTime() - start;
    if (!window.google && currentWait < maxWaitTime) {
      later(() => {
        console.info('waiting until Google places is initialized');
        waitUntilLoad();
      }, waitInterval);
    } else {
      if (window.google) {
        console.info('Google places initialized successfully');
      } else {
        console.error('Google places failed to initialize');
      }
      application.advanceReadiness();
    }
  };

  waitUntilLoad();
}

export default {
  initialize,
};