2

I am using google maps API, and have created a Component to display the map.

index.html:

<!DOCTYPE html>
<html>
<head>
    ...
</head>
<body>
<div id="app"></div>
<!-- built files will be auto injected -->
<script>
window.show_google_map = false;
console.log(window.show_google_map);
function initMap() {
    console.log('map loaded');
    window.show_google_map = true;
    console.log(window.show_google_map);
}
</script>
<script async defer
        src="https://maps.googleapis.com/maps/api/js?key=googleapikeyxxxx&callback=initMap"
        type="text/javascript"></script>
</body>
</html>

GoogleMap.vue:

<template>
    <div class="google_map" :id="map_name"></div>
</template>

<script>
    export default {
        name: 'google_map',
        props: ['map_id'],
        data() {
            return {
                map_name: this.map_id + '-map',
            }
        },
        methods: {
            create_map() {
                const element = document.getElementById(this.map_name);
                const options = {
                    zoom: 14,
                    center: new google.maps.LatLng(51.501527, -0.1921837)
                };
                const map = new google.maps.Map(element, options);
                const position = new google.maps.LatLng(51.501527, -0.1921837);
                const marker = new google.maps.Marker({
                    position,
                    map
                });
            }
        },
        mounted() {
            this.create_map();
        }
    }
</script>

The problem is, the component is rendered before the google maps API is loaded. How can I display after the google maps API has been loaded?

Kakar
  • 5,354
  • 10
  • 55
  • 93

2 Answers2

9

Use the vue.mounted lifecycle method and load the gmaps script manually when the component is mounted for the first time. This way you can kickstart your code after the gmaps api was loaded (works even well for google auth api)

mounted: function () {
    if (window.google && window.google.maps) {
        this.create_map();
        return;
    }

    var self = this;
    var script = document.createElement("script");
    script.onload = function () {
        if (!window.google && !window.google.maps)
            return void (console.error("no google maps script included"));

        self.create_map();
    };

    script.async = true;
    script.defer = true;
    script.src = "https://maps.googleapis.com/maps/api/js?key=googleapikeyxxxx&callback=initMap";
    document.getElementsByTagName("head")[0].appendChild(script);
}
Reiner
  • 1,621
  • 1
  • 16
  • 22
0

If I were you, I'd create a property on the data object called googleMapsReference and assign window.google to it. Then use a watcher to check the value of it with typeof. If it's undefined then you know it hasn't loaded. If you get 'object' then you know it has and you can call the function to create map.

Sorry I'd write code but I'm on my phone.

Here's documentation: https://v2.vuejs.org/v2/guide/computed.html

tony19
  • 125,647
  • 18
  • 229
  • 307
miguelsolano
  • 519
  • 3
  • 11
  • Yes, I am trying that way. But the computed property doesn't fire when it's loaded. I have updated my question. Please have a look. – Kakar Aug 10 '17 at 05:15
  • Oh I wasnt suggesting a computed property. Rather a watcher. It's different than a computed propertyin that it's 2 way bound. – miguelsolano Aug 10 '17 at 05:19
  • You cannot watch a variable that is undefined. – Reiner Aug 10 '17 at 08:53