2

I am trying to render the geocoding service google api mentioned here using VueJS. I am able to do the same thing using normal Javascript and HTML but not able to do same using VueJS. I am not sure how to render it using VueJS.

Here is my index.html code:

<!-- index.html -->

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>VueJS NodeJS and Express example</title>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  </head>
  <body>
    <div id="app"></div>
    <script src="bundle.js"></script>
    <script async defer
    <script src="https://maps.googleapis.com/maps/api/js?key=APIkey&callback=initMap"></script>
    </script>
  </body>
</html>

This is my MapItem.vue file:

<template>
  <div>
    <h1>Mapping api</h1>
    <div id="floating-panel">
      <input id="address" type="textbox" value="Sydney, NSW">
      <input id="submit" type="button" value="Geocode">
    </div>
    <div id="map"></div>
</div>
</template>
<script>
export default {
  data(){
        return{
          item:{}
        }
    },
    methods: {

    initMap() {
        var map = new google.maps.Map(document.getElementById('map'), {
          zoom: 8,
          center: {lat: -34.397, lng: 150.644}
        });
        var geocoder = new google.maps.Geocoder();

        document.getElementById('submit').addEventListener('click', function() {
          geocodeAddress(geocoder, map);
        });
      },
      geocodeAddress(geocoder, resultsMap) {
        var address = document.getElementById('address').value;
        geocoder.geocode({'address': address}, function(results, status) {
          if (status === 'OK') {
            resultsMap.setCenter(results[0].geometry.location);
            var marker = new google.maps.Marker({
              map: resultsMap,
              position: results[0].geometry.location
            });
          } else {
            alert('Geocode was not successful for the following reason: ' + status);
          }
        });
      }
}
}
</script>

<style>

      /* Always set the map height explicitly to define the size of the div
       * element that contains the map. */
      #map {
        height: 100%;
      }
      /* Optional: Makes the sample page fill the window. */
      html, body {
        height: 100%;
        margin: 0;
        padding: 0;
      }
      #floating-panel {
        position: absolute;
        top: 10px;
        left: 25%;
        z-index: 5;
        background-color: #fff;
        padding: 5px;
        border: 1px solid #999;
        text-align: center;
        font-family: 'Roboto','sans-serif';
        line-height: 30px;
        padding-left: 10px;
      }

</style>

Nothing is rendered on my local server when I run it. Any idea?

CodeHunter
  • 2,017
  • 2
  • 21
  • 47

2 Answers2

0

one error i see is how you use geocodeAddress.

Use a arrow function ()=>{} for the event listener callback, so that you can use this as the component instance in the callback.

And call geocodeAddress using this.geocodeAddress, because it's defined as a Vue method

    document.getElementById('submit').addEventListener('click', () => {
        this.geocodeAddress(geocoder, map);
    });

When you are importing this scripts https://maps.googleapis.com/maps/api/js?key=APIkey&callback=initMap (note the callback=initMap), you are telling google map that, after the scripts is loaded, call a function called initMap. This function needs to be in the global scope. But currently it's in the Vue instance.

So you gotta remove callback=initMap from the script tag. And call the initMap function yourself only when you need it.

For e.g., call it when your map component is mounted

mounted() {
  this.initMap();
}
Jacob Goh
  • 19,800
  • 5
  • 53
  • 73
  • still the same. In console, i get this error message: `Kb {message: "initMap is not a function", name: "InvalidValueError", stack: "Error↵ at new Kb (https://maps.googleapis.com/m…aSwRTUupZPE6LanaujGTaQn08&callback=initMap:146:49"}` – CodeHunter Mar 26 '18 at 05:49
  • The issue is that I am not able to invoke initMap() function from the google api script as is being done in the example given at geocode api. – CodeHunter Mar 26 '18 at 05:58
  • I tried removing it from the place you told and call it explicitly when I click submit button on my webpage. It did go inside initMap() method now but doesn't render anything though. – CodeHunter Mar 26 '18 at 06:02
  • nopes. This time I didn't get any console error. The previous error I mentioned was also gone now. Console looks error free. – CodeHunter Mar 26 '18 at 06:04
  • hmm. you may try to find the `#map` element in chrome inspector tools and see if the map is indeed initiated – Jacob Goh Mar 26 '18 at 06:09
  • I don't think the map is actually initiated. I think it is not able to find google.maps component at all which is because it is somehow not able to execute the geocode api script which I mentioned in my index.html page I guess. – CodeHunter Mar 26 '18 at 06:13
0

Your problem is that gmaps api and your component cannot talk. The most easy solution:

  1. Add the following lines to your component:

    mounted: function () {
      var self = this
      // makes the function initMap global available under the vue scope
      window.initMap = function () { self.initMap() }
    }
    

    and do not remove the "callback=initMap" part of your gmaps load script! and you should add a this before geocodeAddress(geocoder, maps) in your initMaps function:

    document.getElementById('submit').addEventListener('click', function() { this.geocodeAddress(geocoder, map); });

  2. More complex option: Load the gmaps api script with vue like i described here https://stackoverflow.com/a/45605316/6355502 and do as described in 1.

PS: There are the lines

 <script async defer
 <script src="https://maps.googleapis.com/maps/api/js?key=APIkey&callback=initMap"></script>

in your code, please remove the first line.

Reiner
  • 1,621
  • 1
  • 16
  • 22
  • It still gives me an error and map do not comes up. The error is that it is still not able to find out initMap function. `Kb {message: "initMap is not a function", name: "InvalidValueError", stack: "Error↵ at new Kb (https://maps.googleapis.com/m…aSwRTUupZPE6LanaujGTaQn08&callback=initMap:146:49"}` – CodeHunter Mar 27 '18 at 03:57
  • Ok thats because you cannot predict when the async script loading is finished! It may end before or after your `mount` hook is called. Please check my Option 2 where the script is loaded manually and because of that predictable. With this technique you can ensure that the `initMap` function and the api are both available – Reiner Mar 27 '18 at 07:19