Rich Bradshaw
Rich Bradshaw

Reputation: 73045

Variable scope in javascript

This is a simple question, but I can't work it out.

The specifics aren't important, but here's the gist. I have some code like this:

var lat = 0;
var lon = 0;

if (navigator.geolocation) {    
    navigator.geolocation.getCurrentPosition(function(position) {
        lat = position.coords.latitude;
        lon = position.coords.longitude;
    });
}

What I think it's doing is:

  1. Set lat and lon to 0
  2. If the browser has geolocation, overwrite those variables with real values

However, at the end of that chunk, lat and lon are still 0. I've tried adding vars, passing lat and lon to the function etc but with no success...

How do I make this work?

Upvotes: 2

Views: 463

Answers (3)

Matthew Flaschen
Matthew Flaschen

Reputation: 285017

It's an async callback. Basically, you pass a function to the the navigator API. Then, your code continues (and does whatever). Later, the navigator API calls your callback with the answer (position). Thus, anything that uses position must be inside (including called by) the callback.

See also this previous answer, which shows how you can create and use a wrapper function.

EDIT: You can simply write a function that calls your callback regardless. If you wanted, getLocation could pass another flag to its argument (e.g. a failure/success code).

function getLocation(callback)
{
    if (navigator.geolocation) {    
        navigator.geolocation.getCurrentPosition(callback);
    }
    else {
        callback(null);
    }
}

Then later:

getLocation(function(pos)
{
  //do stuff
  if(pos != null)
  {
    // loc stuff
  }
  // more stuff
});

You don't have to use anonymous functions.

Upvotes: 6

Amarghosh
Amarghosh

Reputation: 59461

getCurrentPosition() is asynchronous - the values won't be updated instantaneously.

The getCurrentPosition() method takes one, two or three arguments. When called, it must immediately return and then asynchronously attempt to obtain the current location of the device. If the attempt is successful, the successCallback must be invoked (i.e. the handleEvent operation must be called on the callback object) with a new Position object, reflecting the current location of the device. If the attempt fails, the errorCallback must be invoked with a new PositionError object, reflecting the reason for the failure.

alert the values from the function and you'll see the changes. Write the code to perform whatever actions you want inside the function (or abstract them to another function and call it from there) instead of continuing after the if block. For safety, add an error-callback too.

Upvotes: 1

kennytm
kennytm

Reputation: 523674

This has nothing to do with the scope. getCurrentPosition is called asynchronously, that means it will return immediately before the position is received. The function(position) is called only when the geo-position is actually received.

Upvotes: 2

Related Questions