Google geocoding multiple addresses in a loop with javascript, how do I know when everything is done?

user985219 picture user985219 · Jan 29, 2012 · Viewed 17k times · Source

I've got a form that asks for a list of locations (not a lot, normally only 3 or 4 but that number is dynamic). When the form is submitted, I have to parse the data, use Google geocoding to get the locations, and then draw a line connecting the points in order. I have the parsing working, but I'm stuck on the geocoding part, mostly because of the asynchronous nature of it. Assume my address strings are stored in the array 'addresses', this is how far I've gotten:

function someFunction(addresses) {
  var coords = [];
  for(var i = 0; i < addresses.length; i++) {
    currAddress = addresses[i];
    var geocoder = new google.maps.Geocoder();
    if (geocoder) {
      geocoder.geocode({'address':currAddress}, function (results, status)
        if (status == google.maps.GeocoderStatus.OK) {
          coords.push(results[0].geometry.location);
        } 
        else {
          throw('No results found: ' + status);
        }
      });
    }
  }
  // Initially I tried to work with the data here, but it wasn't all present yet.
}

Drawing the line is easy enough, I've done that before when users provided geographic lat/lng coordinates. My problem is, because the coordinates are only added in the callback, how do I know when it's done? I can't just dump that into a function and put in the callback because I need to wait until all the coordinates have been processed.

I also read about someone who had issues with results not coming back in order but I didn't understand the provided response. If someone has an answer that can help me with my specific issue and ensure the results come back in order, I would greatly appreciate.

NB: I hand-bombed that code, so there may be typos. My actual code thus far "works", I just don't know who to move from what I have to doing something once all addresses are processed. Also, this is currently being developed as an internal application for testing. Once testing is finished, it will comply fully with Google's TOS. This means I don't have a page I can link to. The entire application is also over 2,000 lines of code and contains some proprietary company information at this moment which will eventually be phased out, so pasting the entire thing or sending it out isn't feasible. I hope that doesn't pose too big a problem.

Answer

jwchang picture jwchang · Jan 29, 2012
function someFunction(addresses, callback) {
    var coords = [];
    for(var i = 0; i < addresses.length; i++) {
        currAddress = addresses[i];
        var geocoder = new google.maps.Geocoder();
        if (geocoder) {
            geocoder.geocode({'address':currAddress}, function (results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    coords.push(results[0].geometry.location);
                    if(coords.length == addresses.length) {
                        if( typeof callback == 'function' ) {
                            callback();
                        }
                    }
                } 
                else {
                    throw('No results found: ' + status);
                }
            });
        }
     }
  }
}

//Usage
someFunction(addresses, function() {
    // Do something after getting done with Geocoding of multiple addresses
});

Use of Callback function is amazing