vue-google-maps icon indicating copy to clipboard operation
vue-google-maps copied to clipboard

this.$refs.gmap.$mapObject is undefined on mounted

Open davidmondok opened this issue 8 years ago • 11 comments
trafficstars

I'm trying to call this.$refs.gmap.$mapObject.fitBounds(this.googleMapBounds); in the mounted hook, but I get an error Error in mounted hook: "TypeError: Cannot read property '$mapObject' of undefined".

How can I make sure, that the mapObject is available in the mounted hook?

I tried

this.$refs.gmap.$mapCreated.then(() => {
    this.$refs.gmap.$mapObject.fitBounds(this.googleMapBounds);
});

but then I got the error Error in mounted hook: "TypeError: Cannot read property '$mapCreated' of undefined"

Thanks a lot for the help

davidmondok avatar Nov 20 '17 14:11 davidmondok

Is the ref gmap correct? What do you get if you add console.log(this.$refs.gmap) before that snippet?

ah017 avatar Dec 05 '17 09:12 ah017

In practice I have often found that when trying to access refs from the mounted() hook I need to do this

this.$nextTick(() => {
    this.$refs.gmap.$mapCreated.then(() => {
        this.$refs.gmap.$mapObject.fitBounds(this.googleMapBounds);
    })
})

to make sure all children are rendered.

udyux avatar Dec 08 '17 01:12 udyux

Thanks @udyux very helpful. It worth to be mentioned in documentation to avoid a lot of headache!

hassan-jahan avatar Jan 17 '18 22:01 hassan-jahan

for information : $mapCreated became $mapPromise

vwasteels avatar May 31 '18 13:05 vwasteels

@vwasteels Thanks for this precious info !

naimkhalifa avatar Jun 12 '18 08:06 naimkhalifa

Hint : this.$refs.yourRef.$mapObject can be as well undefined if "yourRef" is exactly named "map" (that is, you declare in your template <gmap-map ref="map" ... > and you call it using this.$refs.map.$mapObject). Maybe a reserved property by Vue / Vue Google Maps plugin, or a conflict with Array.map(). Took me some time to figure it out.

mpacary avatar Oct 12 '18 13:10 mpacary

This is how I got mine to work. If you want to use the Google Map PlacesService in any of your Vue methods.

methods: {
           getNearByPlaces:function(place){
			var request = {
				location: place.geometry,
				radius: this.nearByRadius,
				type: this.nearByFilter
			};
			var self = this;
			this.placesService.nearbySearch(request, 
				function (results, status) {
					if(status == google.maps.places.PlacesServiceStatus.OK) {
						self.nearByPlaces = results
					}
				}
			);
		},
},
mounted : function() {
		var self =this;
		self.$refs.mapRef.$mapPromise.then(function(){
		  	self.map =  self.$refs.mapRef.$mapObject;
		  	self.$gmapApiPromiseLazy().then(function(){ 
				self.bounds = new google.maps.LatLngBounds();
				self.placesService = new google.maps.places.PlacesService(self.map);
			})
		})
	},

phprad avatar Oct 21 '18 13:10 phprad

for information : $mapCreated became $mapPromise

@xkjyeah Please include this update in the documentation or somewhere visible, this update may break many builds.

keithgulbroIT avatar Dec 29 '18 06:12 keithgulbroIT

[Vue warn]: Error in mounted hook (Promise/async): "TypeError: Cannot read property 'then' of undefined"

found in

---> <StoreDashboard> at src/views/store/dashboard.vue <Main> at src/layouts/main/Main.vue <App> at src/App.vue <Root>

My Code: this.$refs.mapRef.$mapPromise.then((map) => { map.panTo({lat: 1.38, lng: 103.80}) });

imranamanatcom avatar Feb 20 '20 09:02 imranamanatcom

In 2020, the solution ended up being for me the following:

  1. Adding: autobindAllEvents: true, to your load: {} object within Vue.use (This bit stumped me for the longest is I didn't have autobindAllEvents on).
  2. Add ref="mapRef" to your GMap
  3. In mounted(), write:
this.$nextTick(() => {
 this.$refs.mapRef.$mapPromise.then(() => { // also having anything within the `then()` params caused mapPromise to be undefined... 
    // whatever here.
  })
})

jonathan-bird avatar Nov 11 '20 02:11 jonathan-bird

For folks looking for a Vue 3 / Vue 2 with Composition API version

<template>
  <div class="w-screen h-screen">
    <client-only>
      <!-- Google Map -->
      <gmap-map
        ref="mapRef"
        :center="{
          lat: state.mapCenter.lat,
          lng: state.mapCenter.lng,
        }"
        :options="{
          zoomControl: true,
          mapTypeControl: false,
          scaleControl: true,
          streetViewControl: false,
          rotateControl: false,
          fullscreenControl: false,
          disableDefaultUi: false,
          zoomControlOptions: {
            position: 3,
          },
        }"
        :zoom="7"
        map-type-id="satellite"
        class="min-w-full min-h-full"
      >
        <slot />
      </gmap-map>
    </client-only>
  </div>
</template>

<script lang="ts">
  import {
    defineComponent,
    reactive,
    ref,
    shallowReadonly,
    onMounted,
    nextTick,
  } from '@vue/composition-api';

  export default defineComponent({
    name: 'GoogleMap',
    setup(_, { emit }) {
      const mapRef = ref(null) as any;
      const state = reactive({
        mapCenter: {
          lat: 19.11049824177,
          lng: 72.882502005,
        },
      });
      let map = shallowReadonly({}) as any;
      onMounted(() => {
        nextTick(() => {
          // console.log('mapRef', mapRef.value);
          mapRef.value.$mapPromise.then((m: any) => {
            map = m;
            emit('map-loaded', map);
          });
        });
      });
      return {
        state,
        mapRef,
      };
    },
  });
</script>

vinayakkulkarni avatar Nov 19 '20 20:11 vinayakkulkarni