0

I am kind of stuck inside an 'undefined' exception. I am programming a tool that registers a traveled distance between two places. The application uses google maps distance matrix. When the user picks a vehicle, fills in an origin and a destination, and clicks 'create trip object' a tripObject is created which is then represented inside a div-element. As a basic test the application alerts the distance between the two places in kms. This works fine. But I can't figure out how to register that value inside the tripObject, It keeps giving me an 'undefined' notification when a distance should be displayed inside the div-element, the rest is working fine.

I understand that this notification is caused by some logical mistakes. But for now on I haven't figure out what logical mistake caused this problem. I notice that I am facing these problems frequently. So could anyone explain to me what logical mistake I made?. Below is the code its HTML and Javascript combined.

var lastTripNr = 0;
 
 var distance;
 
 function calculateMapsDistance(orig,dest)
 {
  var calculatedDistance;
  
  var directionsService = new google.maps.DirectionsService();
  
  var request = 
  {
   origin: orig,
   destination: dest,
   travelMode: google.maps.DirectionsTravelMode.DRIVING
  };
  
  directionsService.route(request,function(response,status)
  {
   if (status==google.maps.DirectionsStatus.OK)
   {
    alert((response.routes[0].legs[0].distance.value)/1000);
    calculatedDistance = response.routes[0].legs[0].distance.value /1000;
    
   }
   else
   {
    alert("no route found!");
   }
  });
  
  return calculatedDistance;
  
 }
 
 
 function createTripObject()
 {
  lastTripNr++;
  
  var date = new Date();
  
  var dateString = date.getDate() + "-" + (date.getMonth() + 1) + "-" + date.getFullYear();
  
  var selectionElement = document.getElementById("vehicle");
  var selectedVehicle = selectionElement.options[selectionElement.selectedIndex].value;
  
  var origin = document.getElementById("from").value;
  var destination = document.getElementById("to").value;
  
  var distance = calculateMapsDistance(origin,destination);
  
  var tripObject = 
  {
   nr: lastTripNr,
   date: dateString,
   vehicle: selectedVehicle,
   orig: origin,
   dest: destination,
   dist: distance
  };
  
  document.getElementById("content").innerHTML += "<p>"+tripObject.nr + " | " + tripObject.date + " | " + tripObject.vehicle + " | " + tripObject.orig + " | " + tripObject.dest + " | " + tripObject.dist + 
  "</p>";
  
 }
<html>
<head>
 <title>basic directions service</title>
 <script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
</head>
<body>

<table id="interface">
 <tr>
  <th>vehicle</th>
  <th>from:</th>
  <th>to:</th>
  <th>distance:</th>
 </tr>
 <tr>
  <td>
   <select id="vehicle">
    <option value="Agila">Opel Agila</option>
    <option value="Peugeot">Peugeot 108</option>
    <option value="Atos">Hyundai Atos</option>
    <option value="Matiz">Chevrolet Matiz</option>
    <option value="Overig">overig</option>
   </select>
  </td>
  
  <td><input id="from" type="text"></td>
  <td><input id="to" type="text"></td>
 </tr>
 <tr>
  <td colspan = "4"><button onclick="createTripObject()">create trip object</button></td>
 </tr>
</table>
<div id="content"></div>


<script>
 
</script>
</body>
</html>
geocodezip
  • 158,664
  • 13
  • 220
  • 245
Tim
  • 11
  • 2

2 Answers2

0

Usually, all functions should return ... something.

In "calculateMapsDistance" you return "calculatedDistance".

In "createTripObject" you are not returning anything.

Another way to assign value to an object's property is:

someObject.someProperty = 123

It doesn't matter whether "someProperty" exists or not.

If it exists already it will just replace the existing value with the new value. If it doesn't exist, it will be created first and then it will take the value.

(btw, your code is very well structured, I love the indentation! ;)

tonkatata
  • 369
  • 5
  • 21
  • @Tim - if you share the error code you get after running your code, people will be able to help you debug it quicker. – tonkatata Aug 22 '18 at 21:25
0

You need to keep in mind that the data you use to calculate the distance is loaded asynchronously. So you need to use a callback or promise to wait for that info to be sent back before you add anything to the page.

Here is a JSFiddle where you can see the callback in action.

  directionsService.route(request,function(response,status){
    if (status==google.maps.DirectionsStatus.OK){
     calculatedDistance = response.routes[0].legs[0].distance.value /1000;
     createTripObject(orig,dest, calculatedDistance)
  }
}
Steven Kuipers
  • 809
  • 7
  • 19
  • I was not aware of the concept asynchronous and synchronous. I did some quick research and found out that in essence a called function must be placed below the caller because when a function is called from within another function JS returns to global scope and looks for the called function from top to bottom. Am I right? – Tim Aug 23 '18 at 00:45
  • What you want to do is be sure that the data you are working with has been received. So in the code blurb I posted above we call createTripObject after we have successfully received the asynchronous data. – Steven Kuipers Aug 23 '18 at 09:59