Jamie Woods
Jamie Woods

Reputation: 579

Vue.js breaking Google Map functionality

Currently the code uses Vue.js to manage the inputs and post requests and is using JavaScript to handle things like Google Map functionality.

The issue is that when we wrap a div id around all the current HTML on a page so the Vue.js functionality works, it results in the Google Map code in a JavaScript file to run incorrectly and loads the page with no map. As soon as the Vue.js id (adminVenueVue) is removed the map works fine.

When trying to debug the issue it seems that the function that is responsible for updating the map doesn't run all the way through and stops when a listener function is created as no following code would run after. Below shows this function if you need more code please tell me.

function initCreateUpdateVenue() {
  var mapCenter = new google.maps.LatLng({
    lat: 54.445886,
    lng: -3.435974
  });

  var marker, london = {
    lat: 52.41,
    lng: -1.69
  };

  var ZoomLevel = 5;

  map = new google.maps.Map(document.getElementsByName('googleMap')[0], {
    zoom: ZoomLevel,
    center: mapCenter,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  });

  map.setZoom(5);

  var input = (document.getElementsByName("autocomplete")[0]);
  var options = {
    componentRestrictions: {
      country: "uk"
    }
  };

  var autocomplete = new google.maps.places.Autocomplete(input, options);
  autocomplete.bindTo('bounds', map);

  autocomplete.addListener('place_changed', function() {
    var element = document.getElementsByName("autocomplete")[0];
    //remove any errors
    element.classList.remove("is-invalid");

    var place = autocomplete.getPlace();

    if (!place.geometry) {
      return;
    }

    populate_hidden_fields(place);
    set_venue_detail_fields(place);
    populate_fields(place.address_components);
    set_map_location();
  });
}

Here is the HTML code (the Google Map code is at the bottom)

<div id="adminVenueVue">
  <div class="row">
    <div class="col-lg-12 ">
      <div class="row">
        <div class="col-lg-12 ui-sortable-disabled">
          <div class="panel">
            <div class="panel-heading disable-draggable">Administrator Controls</div>
            <div class="panel-body">
              @include('venue.components.admin_controls', ['submitButtonText' => 'Add Type'])
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-lg-12 ui-sortable-disabled">
          <div class="panel">
            <div class="panel-heading disable-draggable">Start by finding your address</div>
            <div class="panel-body">
              @include('venue.components.autocomplete-form', ['submitButtonText' => 'Add Type'])
            </div>
          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-lg-6 ui-sortable-disabled">
          <div class="panel">
            <div class="panel-heading disable-draggable">Venue Details</div>
            <div class="panel-body" style="padding-bottom: 16px;">
              @include('venue.components.venue-details', ['submitButtonText' => 'Add Type'])
            </div>
          </div>
        </div>
        <div class="col-lg-6 ui-sortable-disabled">
          <div class="panel">
            <div class="panel-heading disable-draggable ">Address Details</div>
            <div class="panel-body">
              @include('venue.components.form', ['submitButtonText' => 'Submit Venue'])
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  <div class="row">
    <div class="col-lg-12 ui-sortable-disabled">
      <div class="panel">
        <div class="panel-heading disable-draggable">Map</div>
        <div class="panel-body">
          <div id="googleMap" name="googleMap" class="width-full" style="height: 500px;"></div>
        </div>
      </div>
    </div>
  </div>
</div>

Upvotes: 0

Views: 1286

Answers (1)

Felipe Thomas
Felipe Thomas

Reputation: 63

I recommend using the Vue google map component (vue2-google-maps).

Follow this example code:

<body>
  <div id="root">
    <google-map :center="{lat: 1.38, lng: 103.8}" :zoom="12" style="width: 100%; height: 500px">
      <ground-overlay source="./overlay.png" :bounds="{
            north: 1.502,
            south: 1.185,
            east: 104.0262,
            west: 103.5998,
        }" :opacity="0.5">
      </ground-overlay>
    </google-map>
  </div>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.0/vue.js"></script>
  <script src="vue-google-maps.js"></script>

  <script>
    Vue.use(VueGoogleMaps, {
      load: {
        key: 'AIzaSyBzlLYISGjL_ovJwAehh6ydhB56fCCpPQw',
        v: '3.26',
      },
      // Demonstrating how we can customize the name of the components
      installComponents: false,
    });
    document.addEventListener('DOMContentLoaded', function() {
      Vue.component('google-map', VueGoogleMaps.Map);
      Vue.component('ground-overlay', VueGoogleMaps.MapElementFactory({
        mappedProps: {
          'opacity': {}
        },
        props: {
          'source': {type: String},
          'bounds': {type: Object},
        },
        events: ['click', 'dblclick'],
        name: 'groundOverlay',
        ctr: () => google.maps.GroundOverlay,
        ctrArgs: (options, {source, bounds}) => [source, bounds, options],
      }));
      new Vue({
        el: '#root',
        data: {
          place: '',
        },
      });
    });
  </script>

</body>

Or, if you're using webpack and Vue file components, follow the instructions bellow.

First install it : npm install vue2-google-maps

Then register it in main.js file

import Vue from 'vue'
import * as VueGoogleMaps from 'vue2-google-maps'

Vue.use(VueGoogleMaps, {
  load: {
    key: 'YOUR_API_TOKEN',
    libraries: 'places', // This is required if you use the Autocomplete plugin
  }
})

So, you can use it like a component:

<GmapMap
  :center="{lat:10, lng:10}"
  :zoom="7"
  map-type-id="terrain"
  style="width: 500px; height: 300px"
>
  <GmapMarker
    :key="index"
    v-for="(m, index) in markers"
    :position="m.position"
    :clickable="true"
    :draggable="true"
    @click="center=m.position"
  />
</GmapMap>

More at: https://www.npmjs.com/package/vue2-google-maps

https://github.com/xkjyeah/vue-google-maps/blob/no-deferred-ready/examples/overlay.html

https://alligator.io/vuejs/vue-google-maps/ (tutorial)

Upvotes: 1

Related Questions