'google' is not defined Using Google Maps JavaScript API Loader

Viewed 3257

I have a Vue CLI project that uses the Google Maps JavaScript API Loader. I import the loader using the code below:

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

After that, I defined the loader, like so:

const loader = new Loader({
  apiKey: "XXXXX",
  version: "weekly",
  libraries: ["places"]
});

Now, when I try to display a map using the google.maps.Map object, I get an error stating that 'google' is not defined. All the code above is in the project's 'main.js' file in the 'src' directory and the code below is the last bit that, unfortunately, triggers the error.

loader.load().then(() => {
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: -34.397, lng: 150.644 },
    zoom: 8,
  });
});

What am I doing wrong?

P.S. I installed @googlemaps/js-api-loader using npm, as per instructions from the Google documentation.

3 Answers

The new package does not return a 'google' object when the promise is resolved, instead it is attached to the window. To use it as you would if following the Vue tutorial (that I am also following) you would need to add:

this.google = window.google

To the map component. For clarity:

async mounted() {
   // As per the documentation for the google maps API loader
   const googleMapApi = await Loader({
       apiKey: this.apiKey
    })

    // This returns a promise, but not a 'google' object
    this.google = await googleMapApi.load();
    // Set the google object from the correct location
    this.google = window.google;
    this.initializeMap();
},

methods: {
    initializeMap() {
        const mapContainer = this.$refs.googleMap;
        this.map = new this.google.maps.Map(mapContainer, this.mapConfig);
    }
}

The reference to the tutorial I talk about: https://v2.vuejs.org/v2/cookbook/practical-use-of-scoped-slots.html

Let’s first establish our GoogleMapLoader.vue template:

<template>
  <div>
    <div class="google-map" ref="googleMap"></div>
    <template v-if="Boolean(this.google) && Boolean(this.map)">
      <slot
        :google="google"
        :map="map"
      />
    </template>
  </div>
</template>

Now, our script needs to pass some props to the component which allows us to set the Google Maps API and Map object:

import GoogleMapsApiLoader from 'google-maps-api-loader'

export default {
  props: {
    mapConfig: Object,
    apiKey: String,
  },

  data() {
    return {
      google: null,
      map: null
    }
  },

  async mounted() {
    const googleMapApi = await GoogleMapsApiLoader({
      apiKey: this.apiKey
    })
    this.google = googleMapApi
    this.initializeMap()
  },

  methods: {
    initializeMap() {
      const mapContainer = this.$refs.googleMap
      this.map = new this.google.maps.Map(
        mapContainer, this.mapConfig
      )
    }
  }
}

Please follow this tutorial for the correct way to do it.

https://v2.vuejs.org/v2/cookbook/practical-use-of-scoped-slots.html

hi @Goodman L you have to try it. Just add window at the front of your code.. happy coding

window.google.maps.Map
Related