Waiting on the Google API, but unfortunately the sleep function is not cooperating

Incorporating the Google Maps API into my svelte project has been a task. I've turned to the js-api-loader npm package for this purpose.

Below is the code snippet I'm using to load the Google API:

loader.js

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

let googleIsLoaded = false;

async function loadGoogleMapsAPI() { 
  if (!googleIsLoaded) {
    const libraries = ['places'];
    try {
      const loader = new Loader({
        apiKey: API_KEY,
        version: 'weekly',
        libraries,
      });
      console.info('Loading Google API ...'); // LOGGED 1st -> OK
      await loader.load();
      console.info('Google API is loaded'); // LOGGED 6th -> KO
      googleIsLoaded = true;
    } catch (error) {
      throw new Error(`Google API Loader failed ${error.message}`);
    }
  }
}

Upon loading the page, it first accesses the route specified in route/index.svelte:

<script context="module">
  export const ssr = false;
</script>

<script>
  import MyComp from '$components/MyComp.svelte';
  import { loadGoogleMapsAPI } from '$lib/loader.js';

  init();

  async function init() {
    try {
      await loadGoogleMapsAPI();
    } catch (e) {
      console.error(e);
    }
  }

  <MyComp />

Subsequently, MyComp.svelte is loaded:

import { onMount } from 'svelte';

let google;
onMount(() => {
    console.log('mounted'); // LOGGED 2nd -> OK
    google = window.google;
    if (google === undefined) {
      console.log('google is undefined'); // LOGGED 3rd -> OK
      sleep(5000, init());
    } else {
      console.log('google is defined');
    }
});

async function init() {
    ...
    autocompleteWidget = new google.maps.places.Autocomplete(input, options); 
/////////// LOGGED 5th -> KO: EXCEPTION GOOGLE IS NOT DEFINED /////////
}

and here's the helper function used for sleeping:

helpers.js


export async function sleep(time, fn, ...args) {
  console.info('sleep ' + time + 'ms');  // LOGGED 4th -> OK
  await timeout(time);
  console.info('woken'); // LOGGED 7th -> KO
  return fn(...args);
}

function timeout(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

However, there seems to be an issue as the `init()` function is invoked disregarding the `sleep(5000, init())` call :/

Thank you for your assistance.

console

loader.js: Loading Google API ...
MyComp.svelte: mounted
MyComp.svelte: google is undefined
helpers.js: sleep 5000ms
MyComp.svelte:106 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'maps')
helpers.js: Google API is loaded
helpers.js: woken

Answer №1

Instead of invoking the function, pass its reference.

Modify

sleep(5000, init());

to:

sleep(5000, init);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the correct method for adding a button to a popup in Leaflet Draw?

I need a button within a popup that can perform an action on the attached layer. L.marker(coors[i], { icon }) .addTo(this.drawnItem) .bindPopup(this._getCustomIcon(mix)) .openPopup(); Here is my _getCustomIcon() function: ...

Exploring Angular 1.x, utilizing both ES5 and ES6, and incorporating Karma for comprehensive testing

I am currently developing tests for an angular app that consists of a mix of ES5 and ES6 files. To transpile the ES6 files, I am using babel CLI with the options --modules system --module-ids. Here is an example of what I have: ES5 file: angular.module(& ...

What is the best way to capture user input using an onClick event in JavaScript and then display it on the screen?

I'm in the process of upgrading a table, and while most of it is working fine, there is one function that's giving me trouble. I want this function to return an input with an inline onClick event. The actual return value is displaying correctly, ...

Is there a way to determine if a click occurred outside of a div without relying on stopPropagation and target event?

My goal is to track multiple div elements and determine if a click occurs outside of any of these divs. I am looking for a solution that does not involve using stopPropagation or event.target as they have negative effects. Is there an alternative method to ...

Use jQuery eq() to populate a group of text fields with data stored in localStorage

In my project, I have a series of text areas that are configured to save their content in localStorage for persistence. As I attempt to retrieve and reassign these values when the browser reloads, I encounter an issue with the following code snippet. When ...

Tips for effectively utilizing axios without Vue.js CLI (for instance, in JS Fiddle)

Currently, I am immersing myself in the world of vue.js. To get a better understanding of the dependencies, I have chosen not to utilize the Vue cli just yet, opting for JS Fiddle instead. My next goal is to interact with an API using axios. Here is a glim ...

Turn off selective bloom in ThreeJS for the background of the scene

I am using ThreeJS to create a selective bloom effect to showcase glowing parts on an object using an emissive map as a filter. I recently enabled my environment map and noticed that the bloom is affecting the appearance of the scene.background. This is t ...

Is it possible to achieve a 300 dpi resolution when printing an HTML page?

I've encountered an issue with my web page. It is encoded in HTML and CSS and designed to be the size of an A4 page (300dpi) at 2480 x 3508 pixels. However, when I try to print the page, it is printing in a resolution of 72/96 dpi and splitting into ...

Showing a nested dataset with a condition: Is there a way to hide the information for products that do not meet the color condition?

I need help refining my code to only display the quantity of colors that are more than 10. Right now, it shows all colors, including those with less than 10. How can I adjust this? Thank you. Find my codesandbox here: https://codesandbox.io/s/products-0cc ...

Chaining based on conditions in JavaScript and TypeScript

How can I conditionally add a function to a chain in JavaScript? For instance, if modifier is true, I want myKey to be required using Joi.string().required(). If it is false, then just use Joi.string(): function customJoi(modifier) { return Joi.object({ ...

Tips for saving images in an S3 bucket

Within my express application, I currently save images to a directory in my repository. However, I am beginning to think that this approach may not be ideal and I am considering using AWS S3 as an alternative storage solution. Since I have never worked w ...

Guide to implementing dynamic conditional rendering in Vue.js loops (utilizing v-if within v-for)

I am currently working on a table component in a .vue file where I want to display icons based on the direction of the order clicked. For example: <th v-for="(column, index) in columns" :key="index" @click="sort( index )"> <span& ...

The OnClientClick function fails to execute

I've been attempting to validate the contactno control using a JavaScript function, but it doesn't seem to be triggered before the OnClick event. This is the JavaScript code I'm using: <script type="text/javascript"> function valida ...

Utilizing CSS to set a map as the background or projecting an equirectangular map in the backdrop

How can I set an equirectangular projection like the one in this example http://bl.ocks.org/mbostock/3757119 as a background for only the chart above the X-axis? Alternatively, is it possible to use an image of a map as a CSS background instead? .grid . ...

What is the best way to efficiently input identical data into multiple controllers ($scope) using just one call in AngularJS?

I have a situation where I am using a factory to make a call in two controllers on the same page. However, I want to avoid making an AJAX call twice. I tried using $q.defer(), but it doesn't seem to be working! Here is the code snippet: (function ...

While attempting to import modules in Visual Studio Code, an error message appears stating "Unexpected token {"

Greetings! I am currently using Visual Code to run my project and would like to share my code with you. In the file external.js: export let keyValue=1000; In the file script.js: import {keyValue} from './external.js'; console.log(keyValue); ...

Struggling to display the default value on a <select> element using the defaultValue prop in React

My objective is to create a dropdown menu that lists all the US state names. If there is a stateName in this.props (obtained from the redux store with values like NY, KY, or an empty string), I want the dropdown to display it by default. Otherwise, I want ...

Using a nodeJS proxy server to capture and manipulate http/https responses

I am working on developing a nodeJS proxy server that can modify the response from a server. My goal is to be able to access google.com without having to navigate to an address like http://localhost:8000/google. The proxy should operate in the background s ...

Tips for getting a sticky table header and including a limited number of columns, each with checkboxes or input fields

Encountering issues while trying to implement functionality with a jQuery library. One specific problem is the inability to interact with checkboxes on sticky columns, as well as difficulties clicking and typing in text fields. I am utilizing the jQuery S ...

Caution: It is essential for each child within a list to possess a distinct "key" property - React Native issue alert

Hello everyone, I am currently working on building a list in an app using react-native. I have been following a tutorial video and my code is identical to the instructor's, but I keep encountering an error that says each child in the list needs a key ...