Ошибки JS при асинхронной загрузке Google Maps API - PullRequest
0 голосов
/ 06 декабря 2018

Как объяснено в этом вопросе, я добавил &callback=initialize к сценарию, который загружает API Карт Google:

<script src="https://maps.googleapis.com/maps/api/js?key=XXXX&amp;callback=initialize&amp;region=it&amp;libraries=places" async defer></script>

Карта загружается, но указания больше не нужныи я получаю следующие ошибки:

Uncaught ReferenceError: google is not defined
    at map.html:15

Uncaught (in promise) TypeError: Cannot read property 'push' of undefined
    at initialize (map.html:60)
    at js?key=XXXX&callback=initialize&region=it&libraries=places:130

Что я делаю не так?

Это функция (я изменил координаты GPS и удалил информацию из метки / адреса для конфиденциальности):

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var mkArray=[];

function initialize() {
directionsDisplay = new google.maps.DirectionsRenderer();
var myLatlng = new google.maps.LatLng(41.389835,12.413704);

var mapOptions = {
    zoom:16,
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    center: myLatlng,
    styles: [
        {
            featureType: "poi.business",
            elementType: "labels",
            stylers: [
                    { visibility: "off" }
            ]
        }
    ]
  }

map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
directionsDisplay.setMap(map);
directionsDisplay.setPanel(document.getElementById('directions-panel'));

var input = document.getElementById('start');
var options = {
    types: ['geocode'],
    componentRestrictions: {country: 'it'},
    rankBy: google.maps.places.RankBy.DISTANCE
};
var bounds = new google.maps.LatLngBounds(
    new google.maps.LatLng(41.76, 12.33),
    new google.maps.LatLng(42.00, 12.64)
);
var autocomplete = new google.maps.places.Autocomplete(input, options);
autocomplete.setBounds(bounds);

var marker = new google.maps.Marker({
    position: myLatlng,
    map: map,
    title: 'XXXXX'
});
mkArray.push(marker);
}

function calcRoute(callback) {
    var start = document.getElementById('start').value;
    var end = "Address, Rome";
    var request = {
        origin:start,
        destination:end,
        travelMode: google.maps.DirectionsTravelMode.TRANSIT
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);

        // If a callback was passed, run it
        if(typeof callback === "function") {
            callback();
        }

      }
    });
    for (var i = 0, j = mkArray.length; i < j; i++) 
      mkArray[i].setMap(null);
}

google.maps.event.addDomListener(window, 'load', initialize);

1 Ответ

0 голосов
/ 06 декабря 2018

Вы пытаетесь использовать google объект перед загрузкой:

var directionsService = new google.maps.DirectionsService()

Вам нужно дождаться, пока ваш обратный вызов initialize будет выполнен, чтобы использовать googleобъект, поэтому мой лучший совет - сделать что-то вроде этого (как вы уже сделали для directionsDisplay):

var directionService;

function initialize() {
   directionsService = new google.maps.DirectionsService();

   // other code here
}

И что вы пытаетесь сделать в своей последней строке?

google.maps.event.addDomListener(window, 'load', initialize);

Вы делаете 2 ошибки здесь:

  1. Все еще пытаетесь использовать google до того, как ваш обратный вызов будет вызван
  2. Вы пытаетесь зарегистрировать одну и ту же функцию как для обратного вызова GMaps API, так и для события окна load.Это не сработает из-за первого пункта, но даже если бы это было так, вы бы в итоге выполнили initialize дважды, и я не думаю, что это то, что вы хотите.
...