1st Dynami c API карт Google autocomplete.getPlace () возвращает ноль - PullRequest
0 голосов
/ 04 февраля 2020

У меня есть 2 поля ввода и доставки. вот вызов библиотеки:

<script async defer
src="https://maps.googleapis.com/maps/api/js?key=mykey&libraries=places&callback=initMap">
</script>

и мой фрагмент автозаполнения:

var inputStart = document.getElementsByClassName('ginput');
    for (var i = 0; i < inputStart.length; i++) {
        var autocomplete = new google.maps.places.Autocomplete(inputStart[i]);
        console.log(autocomplete);
        autocomplete.inputId = inputStart[i].id;
        autocomplete.bindTo('bounds', map);
        autocomplete.setFields(
        ['address_components', 'geometry', 'icon', 'name']);
        var infowindow = new google.maps.InfoWindow();
        var infowindowContent = document.getElementById('infowindow-content');
        infowindow.setContent(infowindowContent);
        var marker = new google.maps.Marker({
            map: map,
            anchorPoint: new google.maps.Point(0, -29)
        });
        autocomplete.addListener('place_changed', function() {
            infowindow.close();
            marker.setVisible(false);
            var place = autocomplete.getPlace();
            console.log(place);
            if (!place.geometry) {
              // User entered the name of a Place that was not suggested and
              // pressed the Enter key, or the Place Details request failed.
              window.alert("No details available for input: '" + place.name + "'");
              return;
            }
            // If the place has a geometry, then present it on a map.
            if (place.geometry.viewport) {
              map.fitBounds(place.geometry.viewport);
            } else {
              map.setCenter(place.geometry.location);
              map.setZoom(17);  // Why 17? Because it looks good.
            }
            marker.setPosition(place.geometry.location);
            marker.setVisible(true);
            var address = '';
              //console.table(place);
            if (place.address_components) {
              address = [
                (place.address_components[0] && place.address_components[0].short_name || ''),
                (place.address_components[1] && place.address_components[1].short_name || ''),
                (place.address_components[2] && place.address_components[2].short_name || ''),
                (place.address_components[6] && place.address_components[6].short_name || '')

              ].join(' ');
            }else{
                alert("No Place");
            }

            infowindowContent.children['place-icon'].src = place.icon;
            //infowindowContent.children['place-name'].textContent = place.name;
            infowindowContent.children['place-address'].textContent = address;
            infowindow.open(map, marker);

HTML:

<b>Pickup:</b>
<div id="pac-container-start">
<input id="pac-input-start" class="ginput" type="text"
    placeholder="Enter a pickup location">
</div>

<b>Dropoff:</b>
<div id="pac-container-end">
<input id="pac-input-end" class="ginput" type="text"
    placeholder="Enter a dropoff location">
</div>

Проблема заключается в выборе адреса из выпадающий список, я получаю сообщение об ошибке:

scripts.js:159 Uncaught TypeError: Cannot read property 'geometry' of undefined

Я вышел из системы, и он не определен, забавно то, что когда я выбираю адрес во 2-м поле, кажется, что он работает нормально. без ошибок, наметить правильные направления и все Мне почти кажется, что он запутался, на какой ящик отправляется запрос? Было бы очень полезно указать мне правильное направление.

1 Ответ

0 голосов
/ 05 февраля 2020

Ваше автозаполнение остается на последнем вводе, поэтому оно больше не работает на первом.

Один из способов исправить это - использовать Array.prototype.forEach для итерации по коллекции входов, давая закрытие функции на каждый экземпляр автозаполнения:

  Array.prototype.forEach.call(inputStart, function(el, i) {
    console.log(inputStart[i].id);
    var autocomplete= new google.maps.places.Autocomplete(inputStart[i]);
    console.log(autocomplete);
    autocomplete.inputId = inputStart[i].id;
    autocomplete.bindTo('bounds', map);
    autocomplete.setFields(
      ['address_components', 'geometry', 'icon', 'name']);
    var infowindow = new google.maps.InfoWindow();
    var infowindowContent = document.getElementById('infowindow-content');
    infowindow.setContent(infowindowContent);
    var marker = new google.maps.Marker({
      map: map,
      anchorPoint: new google.maps.Point(0, -29)
    });
    autocomplete.addListener('place_changed', function() {
      infowindow.close();
      marker.setVisible(false);
      var place = autocomplete.getPlace();
      console.log(place);
      if (!place.geometry) {
        // User entered the name of a Place that was not suggested and
        // pressed the Enter key, or the Place Details request failed.
        window.alert("No details available for input: '" + place.name + "'");
        return;
      }
      // If the place has a geometry, then present it on a map.
      if (place.geometry.viewport) {
        map.fitBounds(place.geometry.viewport);
      } else {
        map.setCenter(place.geometry.location);
        map.setZoom(17); // Why 17? Because it looks good.
      }
      marker.setPosition(place.geometry.location);
      marker.setVisible(true);
      var address = '';
      //console.table(place);
      if (place.address_components) {
        address = [
          (place.address_components[0] && place.address_components[0].short_name || ''),
          (place.address_components[1] && place.address_components[1].short_name || ''),
          (place.address_components[2] && place.address_components[2].short_name || ''),
          (place.address_components[6] && place.address_components[6].short_name || '')

        ].join(' ');
      } else {
        alert("No Place");
      }

      infowindowContent.children['place-icon'].src = place.icon;
      //infowindowContent.children['place-name'].textContent = place.name;
      infowindowContent.children['place-address'].textContent = address;
      infowindow.open(map, marker);
    })
  })

подтверждение концепции скрипта

screenshot of resulting map

фрагмент кода

// This example requires the Places library. Include the libraries=places
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places">
function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: -33.8688,
      lng: 151.2195
    },
    zoom: 13
  });
  var infowindow = new google.maps.InfoWindow();
  var infowindowContent = document.getElementById('infowindow-content');

  var inputStart = document.getElementsByClassName('ginput');
  //for (var i = 0; i < inputStart.length; i++) {
  // inputStart.forEach(function() {
  Array.prototype.forEach.call(inputStart, function(el, i) {
    console.log(inputStart[i].id);
    var autocomplete= new google.maps.places.Autocomplete(inputStart[i]);
    console.log(autocomplete);
    autocomplete.inputId = inputStart[i].id;
    autocomplete.bindTo('bounds', map);
    autocomplete.setFields(
      ['address_components', 'geometry', 'icon', 'name']);
    infowindow.setContent(infowindowContent);
    var marker = new google.maps.Marker({
      map: map,
      anchorPoint: new google.maps.Point(0, -29)
    });
    autocomplete.addListener('place_changed', function() {
      infowindow.close();
      marker.setVisible(false);
      var place = autocomplete.getPlace();
      console.log(place);
      if (!place.geometry) {
        // User entered the name of a Place that was not suggested and
        // pressed the Enter key, or the Place Details request failed.
        window.alert("No details available for input: '" + place.name + "'");
        return;
      }
      // If the place has a geometry, then present it on a map.
      if (place.geometry.viewport) {
        map.fitBounds(place.geometry.viewport);
      } else {
        map.setCenter(place.geometry.location);
        map.setZoom(17); // Why 17? Because it looks good.
      }
      marker.setPosition(place.geometry.location);
      marker.setVisible(true);
      var address = '';
      //console.table(place);
      if (place.address_components) {
        address = [
          (place.address_components[0] && place.address_components[0].short_name || ''),
          (place.address_components[1] && place.address_components[1].short_name || ''),
          (place.address_components[2] && place.address_components[2].short_name || ''),
          (place.address_components[6] && place.address_components[6].short_name || '')

        ].join(' ');
      } else {
        alert("No Place");
      }

      infowindowContent.children['place-icon'].src = place.icon;
      //infowindowContent.children['place-name'].textContent = place.name;
      infowindowContent.children['place-address'].textContent = address;
      infowindow.open(map, marker);
    })
  })
}
/* Always set the map height explicitly to define the size of the div
 * element that contains the map. */
#map {
  height: 80%;
}
/* Optional: Makes the sample page fill the window. */
html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}
#description {
  font-family: Roboto;
  font-size: 15px;
  font-weight: 300;
}

#infowindow-content .title {
  font-weight: bold;
}

#infowindow-content {
  display: none;
}

#map #infowindow-content {
  display: inline;
}

.pac-card {
  margin: 10px 10px 0 0;
  border-radius: 2px 0 0 2px;
  box-sizing: border-box;
  -moz-box-sizing: border-box;
  outline: none;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.3);
  background-color: #fff;
  font-family: Roboto;
}

#pac-container {
  padding-bottom: 12px;
  margin-right: 12px;
}

.pac-controls {
  display: inline-block;
  padding: 5px 11px;
}

.pac-controls label {
  font-family: Roboto;
  font-size: 13px;
  font-weight: 300;
}

.ginput {
  background-color: #fff;
  font-family: Roboto;
  font-size: 15px;
  font-weight: 300;
  margin-left: 12px;
  padding: 0 11px 0 13px;
  text-overflow: ellipsis;
  width: 400px;
}

#pac-input:focus {
  border-color: #4d90fe;
}

#title {
  color: #fff;
  background-color: #4d90fe;
  font-size: 25px;
  font-weight: 500;
  padding: 6px 12px;
}
<div class="pac-card" id="pac-card">
  <div id="pac-container">
    <input id="pac-input" class="ginput" type="text"
        placeholder="Enter a location" value="Potts Point">
    <input id="pac-input2" class="ginput" type="text"
        placeholder="Enter a location" value="Sydney">
  </div>
</div>
<div id="map"></div>
<div id="infowindow-content">
  <img src="" width="16" height="16" id="place-icon">
  <span id="place-name"  class="title"></span><br>
  <span id="place-address"></span>
</div>
<!-- Replace the value of the key parameter with your own API key. -->
<script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap&v=quarterly"
        async defer></script>
...