views:

347

answers:

5

I am working with the google maps API and whenever I return the variable to the initialize function from the codeLatLng function it claims undefined. If I print the variable from the codeLatLng it shows up fine.

  var geocoder;
  function initialize() {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(40.730885,-73.997383);
    var addr = codeLatLng();
    document.write(addr);

  }

  function codeLatLng() {
    var latlng = new google.maps.LatLng(40.730885,-73.997383);
    if (geocoder) {
      geocoder.geocode({'latLng': latlng}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          if (results[1]) {
                return results[1].formatted_address;
          } else {
            alert("No results found");
          }
        } else {
          alert("Geocoder failed due to: " + status);
        }
      });
    }
  }

prints out undefined

If I do:

  var geocoder;
  function initialize() {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(40.730885,-73.997383);
    codeLatLng();


  }

  function codeLatLng() {
    var latlng = new google.maps.LatLng(40.730885,-73.997383);
    if (geocoder) {
      geocoder.geocode({'latLng': latlng}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
          if (results[1]) {
                document.write(results[1].formatted_address);
          } else {
            alert("No results found");
          }
        } else {
          alert("Geocoder failed due to: " + status);
        }
      });
    }
  }

prints out New York, NY 10012, USA

A: 

That return is not returning from codeLatLng; it's returning from the anonymous function being passed to geocoder.geocode.

I think you'll need to pass the data using another mechanism e.g. a global variable

Bobby Jack
A: 

pass geocoder as a parameter to the codeLatLng() function.

function codeLatLng(geocoder) {

call it like so in your initialize function:

var addr = codeLatLng(geocoder);
resopollution
+5  A: 

You're making an asynchronous request, your codeLatLng() function has finished and returned long before the geocoder is done.

If you need the geocoder data to continue, you'll have to chain your functions together:

function initialize() {
    geocoder = new google.maps.Geocoder();
    codeLatLng();
}
function codeLatLng() {
    var latlng = new google.maps.LatLng(40.730885,-73.997383);
    if (geocoder) {
        geocoder.geocode({'latLng': latlng}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                    if (results[1]) {
                        initContinued(results[1].formatted_address);
                    } else {
                        alert("No results found");
                    }
                } else {
                    alert("Geocoder failed due to: " + status);
                }
        });
      }

}
function initContinued(addr) {
    alert(addr);
}
Rob
+5  A: 

You can't return the value from the function, the value doesn't exist yet when the function returns.

The geocode method makes an asynchonous call and uses a callback to handle the result, so you have to do the same in the codeLatLng function:

var geocoder;
function initialize() {
  geocoder = new google.maps.Geocoder();
  var latlng = new google.maps.LatLng(40.730885,-73.997383);
  codeLatLng(function(addr){
    alert(addr);
  });
}

function codeLatLng(callback) {
  var latlng = new google.maps.LatLng(40.730885,-73.997383);
  if (geocoder) {
    geocoder.geocode({'latLng': latlng}, function(results, status) {
      if (status == google.maps.GeocoderStatus.OK) {
        if (results[1]) {
          callback(results[1].formatted_address);
        } else {
          alert("No results found");
        }
      } else {
        alert("Geocoder failed due to: " + status);
      }
    });
  }
}
Guffa
A: 

The geocode function uses a callback (function(results, status) { ... }) which is being called when the geocode function finishes its work. So, when you return a value from this callback, it only returns it to geocode function, not out of the codeLatLng.

With this you have several options: define a variable in codeLatLng and set it in the callback function, for example

function codeLatLng()
{
   var returnValue;

   geocoder.geocode({'latLng': latlng}, function(results, status) { returnValue = results[1].formatted_address });

   return returnValue;
}

Or do the stuff you need with the result directly in the callback function. Or put the result in a global variable. (Also, if the geocode function is asynchronous - if it returns immediately and the callback is called afterwards, you need to do one of the last two, you can't return the value from codeLatLng in that case.)

František Žiačik
Your code example doesn't work. When the variable is returned it's value is not set, as that happens later in the callback function. Using a global variable works for returning the value, but the problem with that is that the code doesn't get any signal when the value is available in the variable. The value is not avaiable immediately after the function is called.
Guffa
That's why I stated that if the geocode is asynchronous (i didn't know whether it was) he should use the other two methods, global variable or do the stuff in callback. Though I admit I didn't point out that with global variable he would not get any signal, so he would have to check for it periodically.
František Žiačik