views:

1829

answers:

4

I have the following code:

var address;
getAddress(0,0);
function getAddress(latlng) 
{
  if (latlng != null) 
  {
    geocoder.getLocations(latlng, 
    function(addresses) 
    {
      if(addresses.Status.code == 200) 
      { 
        address = addresses.Placemark[0].address.toString();
        alert(address);  // Outputs something :)
      }
    });
   }
   return address;   //returns nothing :(
}

I am very new to javascript and don't know why address always returns undefined but the alert does output something.

geocoder is an instance of google maps apis http://code.google.com/apis/maps/documentation/reference.html#GClientGeocoder

+1  A: 

I think that your problems are all related to scope. Generally speaking, you don't want to rely on a global declaration of a variable to be used within the scope of a function.

This should correct any scope issues with your function:

var address = getAddress(0,0);

function getAddress(latlng) {
    if (latlng != null) {
     var address = geocoder.getLocations(latlng, function(addresses) {
      if(addresses.Status.code == 200) { 
       return addresses.Placemark[0].address.toString();
      }
     });
    }
return address;
}
Noah Goodrich
A: 

I can't see any reason why this won't work.

To be doubley sure that nothing returning anything make the function call like this

window.alert(getAddress(0,0));

And then see what is being output

Static Tony
A: 

If I am not mistaken, it looks like

geocoder.getLocations

will not return a value, but expect a callback function, in your case:

function(addresses) {
    if(addresses.Status.code == 200) { 
        return addresses.Placemark[0].address.toString();
    }
}

This "inner" return won't do much, as it will be returning to the insides of geocoder.getLocations.

So, the function doing the assignment is probably being called later than the outer return (the callback and the 200 status suggest that there is a slow http call involved).

That is,unless you can modify geocoder.getLocations the solution will be to make your function functional too, something like:

function getAddress(latlng, callback) {
    if (latlng != null) {
        geocoder.getLocations(latlng, function(addresses){
            if(addresses.Status.code == 200) { 
                address = addresses.Placemark[0].address.toString();
                alert(address);
                //Outputs something :)
                callback(address);
            }
        });
    }

}

and you will call it with something like:

getAddress(ll, function(address){
   alert(address);
});

And as a bonus you can get rid of the global variable :-)

Victor
There is a lot of reading material on functional javascript: http://www.google.com/search?q=functional+javascript
Victor
A: 

I successfully reproduced the error by implementing geocoder.getLocations() to be asynchronous. If geocoder.getLocations() simply executed the parameter function then the change of the variable would become visible before getAddress() returns, so this is not a scope problem.

var address;
alert("B: address returned: " + getAddress());
function getAddress() {
  executeFunction(function() {
    address = "myAddress";
    alert("C: address set to: " + address);
  });
  return address;
}

function executeFunction(aFunction) {
  alert("A: executing: " + aFunction);
  window.setTimeout(aFunction, 1);
}

Executing the code above results in the alert order A-B-C, meaning that address is returned before its assignment. Replacing window.setTimeout(aFunction, 1); with aFunction() results in the order A-C-B, the last alert being "B: address returned: myAddress".

Chei