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! π
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>
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>
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>
So the reason I used metaInfo here is because we can -
- Download external JS files on the go, only when the component is rendered.
- 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>
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>
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-
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.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)
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.
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.
Yes, I'm facing the same issue as well. Did you solve it?
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.
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...
It's working fine in my case. You can login to the website gradbee.com and check.
I like to use APIs, you can find more here: any-api.com
You saved my ars Thank you a lot ;-)
Hi Siddharth,
is it possible to share Github Link ?
Will create a gist / repo soon!
Can you add another tutorial for vue 3 ?
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!
Hi, you can do this :
developers.google.com/maps/documen...
developers.google.com/maps/documen...
This is live on gradbee.com
When you register your account you'll need to enter the location, you can find it there.
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