I'm trying to update a Leaflet map when an address has been selected from the Google Places Autocomplete API.
Bascially, there are two Vue components; My main component "MyPlan.vue" and its child "MyMap.vue".
When I choose an address from the autocomplete search bar, I want the map to move to that latitude and longitude, and I want to adjust the map's zoom to a constant (number), but this isn't working. even though the console.log() is executed and prints the "user picked..." stuff.
I was originially referencing this guide: https://medium.com/dailyjs/google-places-autocomplete-in-vue-js-350aa934b18d
Here is the MyPlan.vue code:
<template>
<div class="container">
<div class="row">
<!-- My Map -->
<div class="col-6">
<h2>This is My Map</h2>
<input type="text"
placeholder="Address"
ref="autocomplete"
id="addressAutocomplete"
/>
<MyMap :plan_apps="planApps" :map_centre="mapCentre" :zoom_="zoom"/>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import MyMap from "./MyMap.vue"
export default {
name: 'MyPlan',
components: {
MyMap
},
data: function() {
return {
planApps: [],
mapCentre: [53.3498, -6.2603],
zoom: 11.5
normalIconSize: [15,15],
largeIconSize: [30,30],
}
},
mounted() {
// Get the points that I want to display on the map from my API/database
// And add an icon size for the markers
axios.get("http://localhost:5000/get/null")
.then((r)=>{
this.planApps = r.data.map(r=>{
r.iconSize = this.normalIconSize;
return r;
})
});
// Set up Google Autocomplete
const google = window.google
const googleOptions = {
types: ['geocode'],
componentRestrictions: {country: 'ie'}
}
this.autocomplete = new google.maps.places.Autocomplete(
(this.$refs.autocomplete),googleOptions
);
this.autocomplete.addListener('place_changed', () => {
let place = this.autocomplete.getPlace();
console.log(place)
let ac = place.address_components;
let area = ac[4]["long_name"];
let lat = place.geometry.location.lat();
let lon = place.geometry.location.lng();
console.log(`The user picked ${area} with the coordinates ${lat}, ${lon}`);
// Update PlanPerm data, which is passed as props to MyMap
this.mapCentre[0] = lat;
this.mapCentre[1] = lon;
this.zoom = 14;
});
}
}
</script>
And Here is the MyMap.vue code:
<template>
<div class="row map">
<l-map
:zoom="zoom_"
:center="latLng(map_centre[0],map_centre[1])"
>
<l-tile-layer
:url="url"
:attribution="attribution"
/>
<l-marker
:key="index"
v-for="(plan,index) in plan_apps"
:lat-lng="latLng(plan.northing,plan.easting)">
<l-icon :icon-size="plan.iconSize"
:icon-url="icon">
</l-icon>
<l-popup>
{{plan.location}}
</l-popup>
</l-marker>
</l-map>
</div>
</template>
<script>
import { latLng } from "leaflet";
import { LMap, LTileLayer, LMarker, LIcon, LPopup} from "vue2-leaflet";
import houseTag from "../assets/houseTag.png"
export default {
name: "MyMap",
components: {
LMap,
LTileLayer,
LMarker,
LIcon,
LPopup
// LTooltip
},
props: {
plan_apps: Array,
map_centre: Array,
zoom_: Number
},
data: function() {
return {
zoom: this.zoom_,
center: latLng(this.map_centre[0],this.map_centre[1]),
url: 'https://tile.thunderforest.com/neighbourhood/{z}/{x}/{y}.png?apikey={{MYAPIKEY}}',
attribution:
'© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
marker: latLng(53.3498, -6.2603),
currentZoom: 11.5,
currentCenter: latLng(53.3498, -6.2603),
// iconSize: [15,15],
icon: houseTag,
showParagraph: false,
mapOptions: {
zoomSnap: 0.5
},
showMap: true
};
},
methods: {
latLng: function(lat,lng) {
return latLng(lat,lng)
}
}
}
</script>
Is it correct to set the listener 'place_changed' for the autcomplete in the mounted function of "MyPlan.vue"?
I have a feeling that I may not be handling the data in the "MyMap.vue" file correctly, as I'm unsure of exactly what the data function is doing and whether there is a need to set many of the variables that I have there, and whether I should be passing the props directly to the map tags within 'template' directly, as I am doing.
I'm pretty new to Vue, and not really familiar with the nuances of JavaScript. Any help or advice would be appreciated.
Thanks!