xkjyeah / vue-google-maps

Google maps component for vue with 2-way data binding
https://xkjyeah.github.io/vue-google-maps/
1.88k stars 474 forks source link

Field does not take the value of the google address #750

Open ingcarloschica opened 3 years ago

ingcarloschica commented 3 years ago

the field autocompletes ... with v-model or: value, it does not take the value from google, it only takes the value entered by keyboard. Any ideas?

daydevelops commented 3 years ago

I am also struggling with this. I am trying to find a way to set the initial address and map marker based on a location loaded into my page but cannot find a way to do it. I can set the address in the text input and have jquery click the button but that does not work.

The function setPlace only gets called when you click one of the suggestions in the dropdown menu provided by google. I tried using jquery to simulate a user performing the right actions but it is messy and didnt end up working. You can call setPlace manually, but you have to pass it the full place object, not just the address in the text input.

daydevelops commented 3 years ago

Alright, its not pretty, but I found a way to do it. Instead of saving the text address in my app, I am saving the whole json object provided from the places API. I figured I was going to need some of that data for a future feature anyway.

When my page loads, I pass in that object as a prop to this vue component. I set up a watcher to listen for when the prop is updated for whenever the dat ais loaded in, and then pass that object to the setPlace and updateMarker methods I have.

In my parent view:

<googlemap v-bind:start="form.location" @updateLocation="updateLocation"></googlemap>

My googlemap component:

<template>
  <div>
    <div>
      <label>
        <gmap-autocomplete @place_changed="setPlace"></gmap-autocomplete>
        <button class="pac-button" @click="updateMarker">Update</button>
      </label>
      <br />
    </div>
    <br />
    <gmap-map :center="center" :zoom="10" style="width:100%;  height: 400px;">
      <gmap-marker :position="marker" @click="center=marker"></gmap-marker>
    </gmap-map>
  </div>
</template>

<script>
export default {
  name: "GoogleMap",
  props: ["start"],
  data() {
    return {
      // default to Montreal to keep it simple
      // change this to whatever makes sense
      center: { lat: 45.508, lng: -73.587 },
      marker: { lat: 45.508, lng: -73.587 },
      places: [],
      currentPlace: null
    };
  },
  watch: {
    start(new_val) {
      this.setPlace(this.start);
      this.updateMarker();
    }
  },

  methods: {
    // receives a place object via the autocomplete component
    setPlace(place) {
      this.currentPlace = place;
    },
    updateMarker() {
      if (this.currentPlace) {
        // if currentPlace comes from the input, lat and lng are functions,
        // if currentPlace comes from json saved in database, they are numbers
        // I hate myself for this
        var location = this.currentPlace.geometry.location;
        if (typeof location.lat === "function") {
          var lat = location.lat();
          var lng = location.lng();
        } else {
          var lat = location.lat;
          var lng = location.lng;
        }

        this.marker = {
          lat: lat,
          lng: lng
        };
        this.center = this.marker;
        this.$emit("updateLocation", this.currentPlace);
      }
    }
  }