Search code examples
javascriptapigoogle-mapsgoogle-placesgoogle-directions-api

Get exception in every input address google map directions problem


I use google map with api places . Fill input origin then destination and set direction between two points. My problem is in every fill input I got this message . Any idea please to resolve this problem . How I can set marker of every point after search , then trace route between two markers enter image description here

<div id="google-map"></div>
<div class="row">
    <div class="fieldlabels">
        <label>Origin: </label>
    </div>
    <div class="location-input">
        <input type="text" id="location1" name="origin" placeholder="Enter a start location..." required />
    </div>
</div>
<!-- Location 2 -->
<div class="row">
    <div class="fieldlabels">
        <label>Destination: </label>
    </div>
    <div class="location-input">
        <input type="text" id="location2" name="destination" placeholder="Enter a last location..." required />
    </div>
</div>

<script>
function initMap() {
    const directionsRenderer = new google.maps.DirectionsRenderer();
    const directionsService = new google.maps.DirectionsService();
    const map1 = new google.maps.Map(document.getElementById("google-map"), {
        zoom: 7,
        center: { lat: 48.85661, lng: 2.35222 },
        disableDefaultUI: true,
    });

    directionsRenderer.setMap(map1);
    directionsRenderer.setPanel(document.getElementById("sidebar"));

    const control = document.getElementById("floating-panel");

    map1.controls[google.maps.ControlPosition.TOP_CENTER].push(control);

    const onChangeHandler = function () {
        calculateAndDisplayRoute(directionsService, directionsRenderer);
    };

    document.getElementById("location1").addEventListener("change", onChangeHandler);
    document.getElementById("location2").addEventListener("change", onChangeHandler);

    originautocomplete = new google.maps.places.Autocomplete(
        /** @type {!HTMLInputElement} */
        (document.getElementById("location1")),
        {
            types: ["geocode"],
        }
    );

    destinationautocomplete = new google.maps.places.Autocomplete(document.getElementById("location2"), {
        types: ["geocode"],
    });
}

function calculateAndDisplayRoute(directionsService, directionsRenderer, status) {
    const start = document.getElementById("location1").value;
    const end = document.getElementById("location2").value;

    directionsService
        .route({
            origin: start,
            destination: end,
            travelMode: google.maps.TravelMode.DRIVING,
        })
        .then((response) => {
            console.log(response);

            directionsRenderer.setDirections(response);
        })
        .catch((e) => window.alert("Directions request failed due to " + status));
}

window.initMap = initMap();
</script>

Solution

  • You have a typo in your code: window.initMap = initMap(); should be window.initMap = initMap; as it is in the Google Examples (i.e. https://developers.google.com/maps/documentation/javascript/examples/directions-simple), calling it like that causes it to execute immediately, before the API has completed loading.

    It would also help to protect against calling the directions service when either the start or the end <input> field does not include anything useful (actually would be best to check that the autocomplete service had actually returned a useful result, like in the answer to: How to get the distance between two locations from a users input or google maps Autocomplete with building not working for routing).

    proof of concept fiddle

    screenshot of map with route on it

    function initMap() {
      console.log("initMap");
      const directionsRenderer = new google.maps.DirectionsRenderer();
      const directionsService = new google.maps.DirectionsService();
      const map1 = new google.maps.Map(document.getElementById("google-map"), {
        zoom: 7,
        center: {
          lat: 48.85661,
          lng: 2.35222
        },
        disableDefaultUI: true,
      });
    
      directionsRenderer.setMap(map1);
      directionsRenderer.setPanel(document.getElementById("sidebar"));
    
      const control = document.getElementById("floating-panel");
    
      map1.controls[google.maps.ControlPosition.TOP_CENTER].push(control);
    
      const onChangeHandler = function() {
        console.log("onChangeHandler");
        calculateAndDisplayRoute(directionsService, directionsRenderer);
      };
    
      document.getElementById("location1").addEventListener("change", onChangeHandler);
      document.getElementById("location2").addEventListener("change", onChangeHandler);
    
      originautocomplete = new google.maps.places.Autocomplete(
        /** @type {!HTMLInputElement} */
        (document.getElementById("location1")), {
          types: ["geocode"],
        }
      );
    
      destinationautocomplete = new google.maps.places.Autocomplete(document.getElementById("location2"), {
        types: ["geocode"],
      });
    }
    
    function calculateAndDisplayRoute(directionsService, directionsRenderer, status) {
      const start = document.getElementById("location1").value;
      const end = document.getElementById("location2").value;
      console.log("start=" + start + " end=" + end);
      // protect against no input.
      if (start == "" || end == "")
        return;
    
      directionsService
        .route({
          origin: start,
          destination: end,
          travelMode: google.maps.TravelMode.DRIVING,
        })
        .then((response) => {
          console.log(response);
    
          directionsRenderer.setDirections(response);
        })
        .catch((e) => window.alert("Directions request failed due to " + status));
    }
    
    window.initMap = initMap;
    /* 
     * Always set the map height explicitly to define the size of the div element
     * that contains the map. 
     */
    
    #google-map {
      height: 80%;
    }
    
    
    /* 
     * Optional: Makes the sample page fill the window. 
     */
    
    html,
    body {
      height: 100%;
      margin: 0;
      padding: 0;
    }
    
    #floating-panel {
      position: absolute;
      top: 10px;
      left: 25%;
      z-index: 5;
      background-color: #fff;
      padding: 5px;
      border: 1px solid #999;
      text-align: center;
      font-family: "Roboto", "sans-serif";
      line-height: 30px;
      padding-left: 10px;
    }
    <!DOCTYPE html>
    <html>
    
    <head>
      <title>Directions Service</title>
      <script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
      <!-- jsFiddle will insert css and js -->
    </head>
    
    <body>
      <div id="google-map"></div>
      <div class="row">
        <div class="fieldlabels">
          <label>Origin: </label>
        </div>
        <div class="location-input">
          <input type="text" id="location1" name="origin" placeholder="Enter a start location..." required/>
        </div>
      </div>
      <!-- Location 2 -->
      <div class="row">
        <div class="fieldlabels">
          <label>Destination: </label>
        </div>
        <div class="location-input">
          <input type="text" id="location2" name="destination" placeholder="Enter a last location..." required/>
        </div>
      </div>
      <script src="https://maps.googleapis.com/maps/api/js?key=AIzaSyCkUOdZ5y7hMm0yrcCQoCvLwzdM6M8s5qk&libraries=places&callback=initMap&v=weekly" defer></script>
    </body>
    
    </html>