DEV Community

Cover image for 😎 Implement Google Maps Autocomplete API | Vue.js
Siddharth Arora
Siddharth Arora

Posted on • Edited on

😎 Implement Google Maps Autocomplete API | Vue.js

This tutorial explains how you can easily implement a Places Autocomplete Service by Google Maps API in vue.js

NOTE: the picture is fancy because I use VUETIFY. This tutorial just explains how Google Places API work, with no CSS! 😐

Alt Text

Checkout this video for a demo

All we need is a vue component and a plugin called vue-meta (I already use it for SEO)

First let’s create a file called Places.vue

// Places.vue

<template>
  <div>
    <input type="text" v-model="location">
    <ul>
      <li v-for="(result, i) in searchResults" :key="i">
        {{ result }} // list of all places
      </li>
    </ul>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

Now add a script tag in the same file and add the following -

// Places.vue

<script>
  export default {
    data: () => ({
      location: '',
      searchResults: [],
      service: null // will reveal this later πŸ•΅οΈ
    })
  }
</script>

Enter fullscreen mode Exit fullscreen mode

Install vue-meta plugin β€” the documentation is very easy and the plugin is installed like any other vue plugin.

Putting the metaInfo hook in Places.vue -

// Places.vue

<script>
  export default {
    data, // already wrote above
    metaInfo () {
      return {
        script: [{
          src: `https://maps.googleapis.com/maps/api/js?key=<YOUR_API_KEY>&libraries=places`,
          async: true,
          defer: true,
          callback: () => this.MapsInit() // will declare it in methods
        }]
      }
    }
  }
</script>

Enter fullscreen mode Exit fullscreen mode

So the reason I used metaInfo here is because we can -

  1. Download external JS files on the go, only when the component is rendered.
  2. It gives us the power of the callback function, called when the JS file is downloaded!β€Šβ€”β€ŠπŸ˜Ž

Now let’s move ahead and create the most awaited methods hook -

// Places.vue

<script>
  export default {
    data // defined already,
    metaInfo // defined already,

    methods: {
      MapsInit () {
        this.service = new window.google.maps.places.AutocompleteService()
      },
      displaySuggestions (predictions, status) {
        if (status !== window.google.maps.places.PlacesServiceStatus.OK) {
          this.searchResults = []
          return
        }
        this.searchResults = predictions.map(prediction => prediction.description) 
      }
    }

  }
</script>

Enter fullscreen mode Exit fullscreen mode

Let's see what these functions MapsInit and displaySuggestions do.

MapInit()β€Š-β€Šthe function that is called when the JS file is loaded.

In this we use a google places service calledβ€Š-β€ŠAutocompleteService (Don't bother right now! Check google documentation if you can't live without it 🀷).

we assign this AutocompleteService() to our data property 'service' so that we can use it again later.

displaySuggestions(predictions, status)β€Š-β€Šexplained a little later.

And this is the last piece of the puzzle. The watcher on the location property

// Places.vue

<script>
  export default {
    data // already defined,
    methods // already defined,
    metaInfo // already defined,
    // the magical part
    watch: {
      location (newValue) {
        if (newValue) {
          this.service.getPlacePredictions({
            input: this.location,
            types: ['(cities)']
          }, this.displaySuggestions)
        }
      }
    }
  }
</script>
Enter fullscreen mode Exit fullscreen mode

So, whatever you type in the input field changes the location property, and whenever the location property is changed, a getPlacePredictions function is called that is attached to the service property.

getPlacePredictions receives two parameters-

  1. An Object that has many things but we only use input and types here-
    a. inputβ€Š-β€Šthe query to be predicted (this.locations in our case).
    b. types - the type of result.

  2. the callback function we declared above in methods hook which isβ€Š-β€ŠdisplaySuggestions.

All done!

If you enjoyed reading this and found it a little helpful,
Consider Buying me a coffee?

Top comments (15)

Collapse
 
felix2056 profile image
CodeBreaker

Since GMAP script tag is added via vue meta and is also responsible for calling MapInit (which is setting the service data), if the component re-mounts or the user briefly navigates away, service will become NULL and the api will stop working.

Collapse
 
pixelsoul profile image
Oliver Kelso

I believe this is true. This is why also it seems, adding more than one of these components to a page won't work, and the service never gets set, and stays null.

Collapse
 
francisjr1997 profile image
francisjr1997

Yes, I'm facing the same issue as well. Did you solve it?

Thread Thread
 
pixelsoul profile image
Oliver Kelso

I did. I just had to change when initmap was called. I think I set a check for it in the watcher for location. When I get back home, I'll double check.

Thread Thread
 
pixelsoul profile image
Oliver Kelso • Edited

So this maybe not the best solution, and there maybe a better a way, but it was done quickly, as I'm still working on this. Here is a gist of the component I have right now. There is a bunch of irrelevant stuff in it for this, but at least it gives you an idea of what I did.

gist.github.com/pixelsoul/8b854e39...

Collapse
 
arora profile image
Siddharth Arora

It's working fine in my case. You can login to the website gradbee.com and check.

Collapse
 
zdev1official profile image
Info Comment hidden by post author - thread only accessible via permalink
ZDev1Official

I like to use APIs, you can find more here: any-api.com

Collapse
 
drd05 profile image
Dr.DoS

You saved my ars Thank you a lot ;-)

Collapse
 
hackwithharsha profile image
Harsha Vardhan

Hi Siddharth,

is it possible to share Github Link ?

Collapse
 
arora profile image
Siddharth Arora • Edited

Will create a gist / repo soon!

Collapse
 
jamols09 profile image
jamols09

Can you add another tutorial for vue 3 ?

Collapse
 
edinfonseca profile image
Edin Fonseca Rangel

Hi, I'm wondering how with this example can I restrict results by country, and how can get addresses results instead of cities. Thanks in advance!

Collapse
 
pierreclouet profile image
PierreClouet
Collapse
 
arora profile image
Siddharth Arora

This is live on gradbee.com
When you register your account you'll need to enter the location, you can find it there.

Collapse
 
eacarras profile image
Aaron Carrasco

This plugin works for vue3 ? I can not search doc how to initialize vue-meta on vue3.

Some comments have been hidden by the post's author - find out more