30

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

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
bmck
  • 755
  • 1
  • 8
  • 19

5 Answers5

51

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
  • 687,336
  • 108
  • 737
  • 1,005
  • is it possible to return value of addr? how should i assign the addr to a variable ? – AbtPst Feb 17 '16 at 22:32
  • @AbtPst: You can't return anything from the result in an asynchronous call, as the call returns before there is a result. Where I placed the `alert(addr);` is where you can use the result. It's possible to assign the value to a global variable there, but then you would still have to wait for the value to arrive. – Guffa Feb 18 '16 at 00:33
  • yes, that would be fine. actually i have an array of lat long values. i want to process the array iteratively and keep adding the address to a list. by the way, is there a way to reverse geocode an array of lat lon values at once? and how do i assign the addr to a global variable? can i just do x=addr inside the function? – AbtPst Feb 18 '16 at 00:39
  • 2
    @AbtPst: I don't know if there is a method for processing multiple coordinates, you have to consult the documentation. Otherwise you would chain the calls, i.e. make another call when one result arrives. To gather the result you might want to use a global array, like `var addresses = [];`, then use `addresses.push(addr);` to add a result. Others doing multiple calls have run into limitations from the server, i.e. after a certain number of calls in a short time it returns an error. So when you get that you would need to wait for a while before attempting again. – Guffa Feb 18 '16 at 00:53
  • This is the best approach due to not having to expose the geocoder results in a global variable. – apebeast Jul 07 '16 at 23:56
  • @Guffa : can u help me refactoring the code for this problem? currently i make a call with async false. http://stackoverflow.com/questions/40291317/javascript-closure-local-variable-nested-function – NeverGiveUp161 Oct 28 '16 at 10:43
11

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
  • 8,042
  • 3
  • 35
  • 37
2

You can get value using localstorage.

 geocoder.geocode({
            'address': address,             
        }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var latitude = results[0].geometry.location.lat();
                var longitude = results[0].geometry.location.lng();
            }                             
           localStorage.setItem("endlat", latitude);
           localStorage.setItem("endlng", longitude);
            });
var end_lat = localStorage.getItem("endlat");
var end_lng = localStorage.getItem("endlng");

But it returns previous value.. Returns current value when we click twice...

vino
  • 107
  • 1
  • 4
-1

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
  • 19,600
  • 10
  • 40
  • 49
-2

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
  • 15,689
  • 15
  • 65
  • 97