3

Possible Duplicate:
JavaScript Variable Scope

i have problem with my script, i want to get value lat, lng from pos function, but when i inspect element in console i get this error :

"Uncaught ReferenceError: lat is not defined TEST.html:30 (anonymous function)"

line 30 is : var latlng = new google.maps.LatLng (lat, lng); This is my full code :

<script type="text/javascript">

navigator.geolocation.getCurrentPosition (function (pos){
  lat = pos.coords.latitude;
  lng = pos.coords.longitude;
});

  var directionsDisplay;
  var directionsService = new google.maps.DirectionsService();
  var map;
  var latlng = new google.maps.LatLng (lat, lng);
  var oceanBeach = new google.maps.LatLng(-6.2501199999999999,106.75937);

  function initialize() {
    directionsDisplay = new google.maps.DirectionsRenderer();
    var mapOptions = {
      zoom: 14,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      center: latlng
    }
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
    directionsDisplay.setMap(map);
  }

  function calcRoute() {
    var selectedMode = document.getElementById("mode").value;
    var request = {
        origin: latlng,
        destination: oceanBeach,
        // Note that Javascript allows us to access the constant
        // using square brackets and a string value as its
        // "property."
        travelMode: google.maps.TravelMode[selectedMode]
    };
    directionsService.route(request, function(response, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(response);
      }
    });
  }
</script>
Community
  • 1
  • 1
  • If that's the code you are using exactly.. the problem is that your lat and lng variables are declared on a different context that the one where you're trying to use them. – Xtian Macedo Jan 29 '13 at 23:43
  • Move the code that comes after the `getCurrentPosition` to the callback function. Since that's where your variables are, doesn't it make sense that that's where the code should be that uses them? – the system Jan 29 '13 at 23:47

2 Answers2

0

You have at least two issues:

  1. The scope of your variables (they are defined in a sub-function and not available in the scope in which you are trying to use them)

  2. The getCurrentPosition() function is asynchronous. That means that it finishes some time AFTER you call it and is completed only when it calls the completion callback function. Thus, it has not yet finished at the time you try to use the results after your function call.

To handle getCurrentPosition() being asynchronous, you would have to do it like this:

navigator.geolocation.getCurrentPosition (function (pos){
    var lat = pos.coords.latitude;
    var lng = pos.coords.longitude;
    var latlng = new google.maps.LatLng (lat, lng);
    var oceanBeach = new google.maps.LatLng(37.7683909618184, -122.51089453697205);      
    // any further code that uses these variables
});

// no code here that uses the results of getCurrentPosition() 
// because it has not completed yet

You can see a similar question and answer here: unable to cope with the asynchronous nature of navigator.geolocation

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • yes you're code it's work well but i need to call var in another function. –  Jan 30 '13 at 00:06
  • @in-c - then you have to call that function from your completion function and pass it this variable. You CAN'T do sequential programming with asynchronous APIs without changing the way you write the code. That's the nature of how they work. You will have to learn how to write code this way to use asynchronous APIs of any kind. This is a very common stumbling block for people learning javascript and asynchronous APIs. The only way around it is to learn the new way you need to write your code. – jfriend00 Jan 30 '13 at 00:09
0

Would it be an issue if you write it like :

navigator.geolocation.getCurrentPosition (function (pos){
     var lat = pos.coords.latitude;
     var lng = pos.coords.longitude;
     var latlng = new google.maps.LatLng (lat, lng);
     var oceanBeach = new google.maps.LatLng(37.7683909618184, -122.51089453697205);
});

The reason it yells is because lat is defined in a different scope to the latlng and oceanBeach that is defined outside of the callback function, and it has no access to it there

UPDATE

Taking your situation into account, you can use a callback to solve your issues, ie doing something like making getCurrentPosition into its own function like :

 function getCurrentLocation(callback) {
   if(navigator.geolocation) {
     navigator.geolocation.getCurrentPosition(function(pos) {
     var lat = pos.coords.latitude;
     var lng = pos.coords.longitude;
     callback(new google.maps.LatLng(lat,lng), new google.maps.LatLng(-6.2501199999999999,106.75937));
   });
  }
  else {
   throw new Error("Your browser does not support geolocation.");     
  }
} 

and calling them with separate callbacks for each ie doing

   getCurrentLocation(function(latlng,oceanBeach){
  // work with latlng and ocean beach here
  });

and now finally calling the function from each function i.e

<script type="text/javascript">

var directionsDisplay;
var directionsService = new google.maps.DirectionsService();

function initialize() {
 getCurrentLocation(function(latlng,oceanBeach){
   directionsDisplay = new google.maps.DirectionsRenderer();
   var mapOptions = {
   zoom: 14,
   mapTypeId: google.maps.MapTypeId.ROADMAP,
   center: latlng
   }
   map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
   directionsDisplay.setMap(map);
 });

}

</script>

and using the same technique for calcRoute. Note : Instead of keeping directionsDisplay and directionsService global you should make this entire thing into a class,so that its cleaner, and more Object oriented

Rahul
  • 391
  • 4
  • 17
  • yes you're true but i need to call it in another function, i edit and add my full code, please read it, thank's –  Jan 30 '13 at 00:04
  • you need to refactor your code so that latlng is available per function call then. you could either make navigator.geolocation.getCurrentPosition into its own function and get latlng values from it for each function or keep latlng globally [which I don't recommend] – Rahul Jan 30 '13 at 00:11
  • I also updated my answer to solve your situation – Rahul Jan 30 '13 at 00:42
  • thank's map is showing but i cant get dirrection. –  Jan 30 '13 at 00:52
  • I'm sorry, are you referring to directionsDisplay not being visible? – Rahul Jan 30 '13 at 00:55
  • yes, before i change function calcRoute() and function initialize() with : getCurrentLocation(function(latlng,oceanBeach) i'm defined but it's no problem i will learn hard for get solusion, thank's. –  Jan 30 '13 at 01:01
  • Please see the way I have coded initialize(). The variables directionsDisplay and directionsService would be available to all functions, when then onload function is called, so directionsDisplay would be visible to it – Rahul Jan 30 '13 at 01:06
  • i already try that, when i try that i get error message : Uncaught SyntaxError: Unexpected end of input but when i remove function initialize() it's work no error but dirrection not not appear. –  Jan 30 '13 at 01:10
  • I'm not really running this code, so I can't really tell where the syntax error is. Could you please provide me some more information? ie the line its complaining about maybe? – Rahul Jan 30 '13 at 01:18