0

I've got the following code which gets the list of addresses from php script, then makes an ajax request to google maps, then creates markers and changes the zoom to fit the markers.

var bounds = new google.maps.LatLngBounds();
$.getJSON('/dmvfinder/dmvsearch.php', {zipcode: zipcode, state: state, city: city}, function (addresses) {
 addresses.forEach(function(address){
  $.getJSON('http://maps.googleapis.com/maps/api/geocode/json', {address: address}, function(data){
    var p = data.results[0].geometry.location;
    var latlng = new google.maps.LatLng(p.lat, p.lng);
    var marker = new google.maps.Marker({
     position: latlng,
     map: map
    });
    bounds.extend(latlng);
  });
 });
});
map.fitBounds(bounds);

As far as i understand the problem with the code is that the fitBounds method fires before ajax finishes and the 'bounds' gets filled. How could i possibly defer the last line of code here?

Thank you in advance!

1 Answers1

1

You need to change 2 things

  1. Accumulate all the promises from the address.forEach - change it to a map and make sure to return $.getJSON(..). This will give you an array of deferreds.
  2. Wait for them all to complete using $.when - as this takes arguments, not an array, you can use $.when.apply(..) on your array from 1)

Like this:

var bounds = new google.maps.LatLngBounds();
$.getJSON('/dmvfinder/dmvsearch.php', {zipcode: zipcode, state: state, city: city}, function (addresses) {
    // 1. Accumulate all the promises into an array
    var allPromises = addresses.map(function(address){
        return $.getJSON('http://maps.googleapis.com/maps/api/geocode/json', {address: address}, function(data){
            var p = data.results[0].geometry.location;
            var latlng = new google.maps.LatLng(p.lat, p.lng);
            var marker = new google.maps.Marker({
                position: latlng,
                map: map
            });
            bounds.extend(latlng);
        });
    });
    // 2. wait for them all to complete
    $.when.apply($,allPromises).then(function(){
      map.fitBounds(bounds);
    })
});
Jamiec
  • 133,658
  • 13
  • 134
  • 193
  • Great, answer but I am not able to understand allDeferreds properly, would you explain a bit more about it? – Parag Bhayani Sep 08 '16 at 14:00
  • @ParagBhayani look up what [`Array.map`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/map) does, and also what the return type of [`$.getJSON`](http://api.jquery.com/jquery.getjson/) is. – Jamiec Sep 08 '16 at 14:01
  • nice - I would dispense with the allDeferreds var myself ... `$.when.apply($, addresses.map(function(address) {` ... `}).then(...);` - but that's what I was in the middle of typing when your answer popped up :p – Jaromanda X Sep 08 '16 at 14:03
  • @JaromandaX thats going to be long and unweildly line of code. I would prefer to see what its doing - especially for explaining an answer. ie - it matches my 1. & 2. – Jamiec Sep 08 '16 at 14:03