0

I have 2 functions, function A calls function B which geocodes an address and returns the LatLng object back to function A but somehow, function A doesn't wait for function B to return result from Google.

function A() {
    var address = document.getElementById("txtbox").value;
    //geocoding here
    var here = B(address);
    if (here == null) {
        console.log("seems like geocode didn't work, defaulting value");

and in function B

function B(address) {
    var here;
    geocoder = new google.maps.Geocoder();
    geocoder.geocode( { 'address': address}, function(results, status) {
        console.log("geocoding");                                               
        if (status == google.maps.GeocoderStatus.OK) {
            console.log(results[0].geometry.location);
            currentlatlng = results[0].geometry.location;
            lng = currentlatlng.lng();
            lat = currentlatlng.lat();
            here = new google.maps.LatLng(lat, lng);
        } else {
            console.log("Geocode was not successful for the following reason: " + status);
        }
    });

    return here;
}

but seems like the output for the console is

seems like geocode didn't work, defaulting value
geocoding

hence, it seems like function A calls function B and then proceeds it..

i thought it would wait but then again as per my understanding of how google maps api work, it doesn't 'wait' per se, so what should i do?

Chen-Tsu Lin
  • 22,876
  • 16
  • 53
  • 63
acvon
  • 161
  • 3
  • 6
  • 21
  • apologies for the duplicate but i have accepted the answer that works thanks @jfriend00 – acvon Feb 27 '14 at 15:40

2 Answers2

6

Your geocode function is Asynchronous. It does not wait. It's result come from an Ajax call (the "A" in "Ajax" stands for Asynchronous).

You cannot program with asynchronous functions in a synchronous manner. Instead, you must use asynchronous techniques with them. In this case, any code that you want to run AFTER you've obtained the geocode information MUST be executed or called from within the completion handler for the geocode operation. You can't execute it after B(). You have to execute it within the completion handler inside of B().

If you want to be able to use B() for multiple purposes, then you can pass a callback into B() and call that callback called when the geocode data is available.

function A(){
    var address = document.getElementById("txtbox").value;
   //geocoding here
    B(address, function(geocodeData) {
        // use geocode data here
    });
}

function B(address, callback){
    var geocoder = new google.maps.Geocoder();
    geocoder.geocode( { 'address': address}, function(results, status) {
         console.log("geocoding");                                              
         if (status == google.maps.GeocoderStatus.OK) {
             console.log(results[0].geometry.location);
             var currentlatlng = results[0].geometry.location;
             var lng = currentlatlng.lng();
             var lat = currentlatlng.lat();
             var here = new google.maps.LatLng(lat, lng);
             // call your callback here and pass it the data
             callback(here);
         }else {
             console.log("Geocode was not successful for the following reason: " + status);
             }
        });
}

FYI, your variables should probably be declared as local variables (with var in front of them) and this is even more important in asynchronous functions.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
0

B makes an asynchronous call, which means that there are no guarantees about order of execution. your best bet is that execution will have arrived at the test in A (long) before here has been initialized in the callback function registered in B.

basically, whatever you want to do with here has to be called from inside the callback after here has been initialized. have a look at jquery, a cross-browser js library which formalizes this pattern of delayed execution with Deferred objects. In particular it comes with an ajax method with user-definable callbacks called on success and on failure.

collapsar
  • 17,010
  • 4
  • 35
  • 61