1

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:
          '&copy; <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!

Peter
  • 21
  • 3

0 Answers0