-2

I use Google Maps Distance Service API to get driving distance and time between two points. Here's my code:

<div id="right-panel">
  <div id="output"></div>
</div>
<div id="map"></div>
<script>

  function initMap() {
    var bounds = new google.maps.LatLngBounds;
    var markersArray = [];

    var origin1 = "<?php echo $partenza; ?>";
    var destinationA = "<?php echo $destinazione; ?>";

    var destinationIcon = 'https://chart.googleapis.com/chart?' +
        'chst=d_map_pin_letter&chld=D|FF0000|000000';
    var originIcon = 'https://chart.googleapis.com/chart?' +
        'chst=d_map_pin_letter&chld=O|FFFF00|000000';
    var map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: 55.53, lng: 9.4},
      zoom: 10
    });
    var geocoder = new google.maps.Geocoder;

    var service = new google.maps.DistanceMatrixService;

    distanza = 0;
    service.getDistanceMatrix({
      origins: [origin1],
      destinations: [destinationA],
      travelMode: 'DRIVING',
      unitSystem: google.maps.UnitSystem.METRIC,
      avoidHighways: false,
      avoidTolls: false
    }, function(response, status) {
      if (status !== 'OK') {
        alert('Error was: ' + status);
      } else {
        var originList = response.originAddresses;
        var destinationList = response.destinationAddresses;
        var outputDiv = document.getElementById('output');
        outputDiv.innerHTML = '';
        deleteMarkers(markersArray);

        var showGeocodedAddressOnMap = function(asDestination) {
          var icon = asDestination ? destinationIcon : originIcon;
          return function(results, status) {
            if (status === 'OK') {
              map.fitBounds(bounds.extend(results[0].geometry.location));
              markersArray.push(new google.maps.Marker({
                map: map,
                position: results[0].geometry.location,
                icon: icon
              }));
            } else {
              alert('Geocode was not successful due to: ' + status);
            }
          };
        };


        results = response.rows[0].elements;
        geocoder.geocode({'address': originList[0]},
            showGeocodedAddressOnMap(false));

          geocoder.geocode({'address': destinationList[0]},
              showGeocodedAddressOnMap(true));
          outputDiv.innerHTML += results[0].distance.text + ' in ' +
              results[0].duration.text + '<br>';

              distanza = results[0].distance.value;
              durata = results[0].duration.value;

            document.innerHTML = distanza + "<br>" + durata;

      }
    });
  }

  function deleteMarkers(markersArray) {
    for (var i = 0; i < markersArray.length; i++) {
      markersArray[i].setMap(null);
    }
    markersArray = [];
  }

  console.log("Distanza: "+distanza);
  console.log("Durata: "+durata);

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

I would like to get the distance and time between the points with a "console.log", but when I type console.log("Distanza: "+distanza); the javascript console says: "distanza is not defined"... How could I access these two variables also outside the function?

loreeemartiii
  • 355
  • 5
  • 14
  • my php variables are ok. I tried to declare distanza and durata at the top of the script but when i call a console.log al the end, they are undefined – loreeemartiii Jun 12 '18 at 12:02
  • 1
    @EmptyBrain this is true but alone will not solve OP's issues as these variables are set in an async function. They will always be undefined if you log them there. – MrUpsidown Jun 12 '18 at 13:40
  • @MrUpsidown Yes, you are right. – Empty Brain Jun 12 '18 at 18:42

1 Answers1

0

There are multiple issues in the code you posted that I can see by just having a quick look (understand: I did not test it).

Declare your variables properly. Like var distanza = 0; that would be the first advice.

Also if you declare a variable within a function, it will only be available from within that function. That is called variables scope. If you need a variable to be available in other places, declare it in the global scope (outside of any function).

Then you should do your console.log within your showGeocodedAddressOnMap which is the callback function you used for the geocoder. Geocoder is asynchronous, so at the point where you do your console.log, it is very likely that the geocoder has not returned anything yet.

Below is an untested, corrected version of your code.

var durata, distanza;

function initMap() {
  var bounds = new google.maps.LatLngBounds;
  var markersArray = [];

  var origin1 = "<?php echo $partenza; ?>";
  var destinationA = "<?php echo $destinazione; ?>";

  var destinationIcon = 'https://chart.googleapis.com/chart?' +
    'chst=d_map_pin_letter&chld=D|FF0000|000000';
  var originIcon = 'https://chart.googleapis.com/chart?' +
    'chst=d_map_pin_letter&chld=O|FFFF00|000000';
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {
      lat: 55.53,
      lng: 9.4
    },
    zoom: 10
  });
  var geocoder = new google.maps.Geocoder;

  var service = new google.maps.DistanceMatrixService;

  distanza = 0;
  service.getDistanceMatrix({
    origins: [origin1],
    destinations: [destinationA],
    travelMode: 'DRIVING',
    unitSystem: google.maps.UnitSystem.METRIC,
    avoidHighways: false,
    avoidTolls: false
  }, function(response, status) {
    if (status !== 'OK') {
      alert('Error was: ' + status);
    } else {
      var originList = response.originAddresses;
      var destinationList = response.destinationAddresses;
      var outputDiv = document.getElementById('output');
      outputDiv.innerHTML = '';
      deleteMarkers(markersArray);

      var showGeocodedAddressOnMap = function(asDestination) {
        var icon = asDestination ? destinationIcon : originIcon;
        return function(results, status) {
          if (status === 'OK') {
            map.fitBounds(bounds.extend(results[0].geometry.location));
            markersArray.push(new google.maps.Marker({
              map: map,
              position: results[0].geometry.location,
              icon: icon
            }));

            distanza = results[0].distance.value;
            durata = results[0].duration.value;

            console.log("Distanza: " + distanza);
            console.log("Durata: " + durata);

          } else {
            alert('Geocode was not successful due to: ' + status);
          }
        };
      };


      results = response.rows[0].elements;
      geocoder.geocode({
          'address': originList[0]
        },
        showGeocodedAddressOnMap(false));

      geocoder.geocode({
          'address': destinationList[0]
        },
        showGeocodedAddressOnMap(true));
      outputDiv.innerHTML += results[0].distance.text + ' in ' +
        results[0].duration.text + '<br>';

      distanza = results[0].distance.value;
      durata = results[0].duration.value;

      document.innerHTML = distanza + "<br>" + durata;

    }
  });
}

function deleteMarkers(markersArray) {
  for (var i = 0; i < markersArray.length; i++) {
    markersArray[i].setMap(null);
  }
  markersArray = [];
}
MrUpsidown
  • 21,592
  • 15
  • 77
  • 131
  • I tryed your code, I add a console.log(distanza) at the end of the script ouside all functions but it return "undefined"... – loreeemartiii Jun 12 '18 at 12:00
  • Please read my answer again: *Then you should do your `console.log` within your `showGeocodedAddressOnMap` which is the callback function you used for the geocoder. Geocoder is asynchronous, so at the point where you do your console.log, it is very likely that the geocoder has not returned anything yet.* – MrUpsidown Jun 12 '18 at 12:24
  • I need the distance in another page, i was thinking to use Ajax and parse the response looking for the variable, is there a better way that accessing javascript variable? – loreeemartiii Jun 12 '18 at 16:07
  • This is javascript. So how could you access a JS variable other than with JS... I don't know. – MrUpsidown Jun 12 '18 at 18:32