google is not defined when using vue2-google-maps

1.5k views Asked by At

I am using Nuxt and vue2-google-maps but I do have the following error

module error: google is not defined

I read the official GitHub FAQ, so I used this.$gmapApiPromiseLazy().then(). But, I do have the aforementioned error.
getCurrentPositionandBathroom method is to get current position and search for convenience store around current position.

<template>
  <v-app>
    <v-btn class="blue white--text" @click="getCurrentPositionandBathroom"> search for bathroom! </v-btn>
    <GmapMap
      ref="mapRef"
      :center="maplocation"
      :zoom="15"
      map-type-id="roadmap"
      style="height: 300px; width: 900px"
    >
      <GmapMarker
        v-for="m in markers"
        :key="m.id"
        :position="m.position"
        :clickable="true"
        :draggable="true"
        :icon="m.icon"
        @click="center = m.position"
      />
    </GmapMap>
  </v-app>
</template>

<script>
export default {
  data() {
    return {
      maplocation: { lat: 35.6814366, lng: 139.767157 },
      markers: [],
    }
  },
  methods: {
    getCurrentPositionandBathroom() {
      if (process.client) {
        if (!navigator.geolocation) {
          alert('Japanese sentences')
          return
        }
        navigator.geolocation.getCurrentPosition(this.success, this.error)
      }
    },
    success(position) {
      this.maplocation.lat = position.coords.latitude
      this.maplocation.lng = position.coords.longitude
      this.$gmapApiPromiseLazy().then(() => {
        google.maps.event.addListenerOnce(
          this.$refs.mapRef.$mapObject,
          'idle',
          function () {
            this.getBathroom()
          }.bind(this),
        )
      })
    },
    getBathroom() {
      const map = this.$refs.mapRef.$mapObject
      const placeService = new google.maps.places.PlacesService(map)
      placeService.nearbySearch(
        {
          location: new google.maps.LatLng(this.maplocation.lat, this.maplocation.lng),
          radius: 500,
          type: ['convenience_store'],
        },
        function (results, status) {
          if (status === google.maps.places.PlacesServiceStatus.OK) {
            results.forEach((place) => {
              const icon = {
                url: place.icon,
                scaledSize: new google.maps.Size(30, 30),
              }
              const marker = {
                position: place.geometry.location,
                icon,
                title: place.name,
                id: place.place_id,
              }
              this.markers.push(marker)
            })
          }
        }.bind(this),
      )
    },
    error(errorMessage) {
      switch (errorMessage.code) {
        case 1:
          alert('Japanese sentences')
          break
        case 2:
          alert('Japanese sentences')
          break
        case 3:
          alert('Japanese sentences')
          break
        default:
          alert('Japanese sentences')
          break
      }
    },
  },
}
</script>

What I should I do?

PS: I can see the Google Maps. In other words, Google Maps is displayed.

1

There are 1 answers

1
kissu On BEST ANSWER

Alright, so there was quite a few configuration to do but I achieved to have a working map. Your this.getBathroom() method was not working for me, but this is related to the API or how you handle the logic I guess.

I basically followed the package README and it all went smooth at the end. Nothing special and google is available as explained in the following section:

If you need to gain access to the google object

Here is the final code of the .vue file

<template>
  <div>
    <button class="blue white--text" @click="getCurrentPositionandBathroom">
      search for bathroom!
    </button>
    <GmapMap
      ref="mapRef"
      :center="maplocation"
      :zoom="15"
      map-type-id="roadmap"
      style="height: 300px; width: 900px"
    >
      <GmapMarker
        v-for="m in markers"
        :key="m.id"
        :position="m.position"
        :clickable="true"
        :draggable="true"
        :icon="m.icon"
        @click="center = m.position"
      />
    </GmapMap>
  </div>
</template>

<script>
import { gmapApi } from 'vue2-google-maps'

export default {
  data() {
    return {
      maplocation: { lat: 35.6814366, lng: 139.767157 },
      markers: [],
    }
  },
  computed: {
    google: gmapApi,
  },
  methods: {
    getCurrentPositionandBathroom() {
      if (process.client) {
        if (!navigator.geolocation) {
          alert('Japanese sentences')
          return
        }
        navigator.geolocation.getCurrentPosition(this.success, this.error)
      }
    },
    success(position) {
      this.maplocation.lat = position.coords.latitude
      this.maplocation.lng = position.coords.longitude
      // this.$gmapApiPromiseLazy().then(() => { // not needed here anymore
      this.google.maps.event.addListenerOnce(
        this.$refs.mapRef.$mapObject,
        'idle',
        function () {
          this.getBathroom()
        }.bind(this)
      )
      // })
    },
    getBathroom() {
      const map = this.$refs.mapRef.$mapObject
      const placeService = new this.google.maps.places.PlacesService(map)
      placeService.nearbySearch(
        {
          location: new this.google.maps.LatLng(
            this.maplocation.lat,
            this.maplocation.lng
          ),
          radius: 500,
          type: ['convenience_store'],
        },
        function (results, status) {
          if (status === this.google.maps.places.PlacesServiceStatus.OK) {
            results.forEach((place) => {
              const icon = {
                url: place.icon,
                scaledSize: new this.google.maps.Size(30, 30),
              }
              const marker = {
                position: place.geometry.location,
                icon,
                title: place.name,
                id: place.place_id,
              }
              this.markers.push(marker)
            })
          }
        }.bind(this)
      )
    },
    error(errorMessage) {
      switch (errorMessage.code) {
        case 1:
          alert('Japanese sentences')
          break
        case 2:
          alert('Japanese sentences')
          break
        case 3:
          alert('Japanese sentences')
          break
        default:
          alert('Japanese sentences')
          break
      }
    },
  },
}
</script>

You can find the useful commit on my github repo here.

This is how it looks at the end, no errors so far.

enter image description here

PS: I didn't saw that you were using Vuetify, so I didn't bother bringing it back later on.