awestover89
awestover89

Reputation: 1763

Google Maps Asynchronously Add Markers

I am playing around with the Google Maps API and want to load a map, then use the bounds to hit an external API to get current weather conditions for a number of cities in the map. The problem I am running into is that if I have async: false it works fine, but once I set async: true the markers no longer load. Here's what I have, I get the feeling it's something really simple.

function initialize()
{
  var mapProp = {
    center: new google.maps.LatLng(41.8369,-95.6847),
    zoom:4,
    disableDefaultUI:true,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };
  map = new google.maps.Map(document.getElementById("googleMap"),mapProp);

  google.maps.event.addListener(map, 'bounds_changed', function() {
      calcBounds();
  });

function calcBounds() {
  var bounds = map.getBounds();
  var ne = bounds.getNorthEast();
  var sw = bounds.getSouthWest();
  for (var lat = ne.lat(); lat > sw.lat(); lat = lat - 5) {
    for (var long = ne.lng(); long > sw.lng(); long = long - 5) {
      $.ajax({
        async: false,
        url: 'http://api.openweathermap.org/data/2.5/weather?lat=' + lat + '&lon=' + long + '&APPID=' + apikey,
        dataType: "json",
        success: function(data) {
          var marker = new google.maps.Marker({
            map: map,
            position: new google.maps.LatLng(lat, long),
          });//End Marker
        },//End Success
        error: function() {
         alert("ERROR");
        }
      });//End AJAX
    }//End Long for
  }//End lat For
}//End function

Upvotes: 2

Views: 4292

Answers (1)

Ray Suelzer
Ray Suelzer

Reputation: 4107

The problem you have is a common one for people learning Javascript. What is happening is that every time you go through one iteration of the loop the value of lat & long is changed. This becomes a problem because your ajax functions are referencing this variable! So, in practice this means that all of your web requests will be for the same lat and long because the loop has likely already finished before the first ajax request has even been sent... It takes about 5ms to do one of these loops and closer to 50-100ms to send and receive an ajax request. Setting it to async: false works (but it freezes the browser!) because it waits until the request has been sent and returned before changing the value of the lat and long variables. So, clearly you want the ajax request to remember the value you want it to look up and not the value that is memory right now. The solution is to put the variables you are going to use in a closure, so that they stay local to ajax function and don't get changed on the next iteration of the loop.

Here is a working example. and a jsfiddle: http://jsfiddle.net/47b3mjn3/2/

  function initialize() {
    var mapProp = {
        center: new google.maps.LatLng(41.8369, -95.6847),
        zoom: 4,
        disableDefaultUI: true,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    };
    map = new google.maps.Map(document.getElementById("googleMap"), mapProp);

    google.maps.event.addListener(map, 'bounds_changed', function () {
        calcBounds();
    });

    function calcBounds() {
        var bounds = map.getBounds();
        var ne = bounds.getNorthEast();
        var sw = bounds.getSouthWest();
        for (var lat = ne.lat(); lat > sw.lat(); lat = lat - 5) {
            for (var long = ne.lng(); long > sw.lng(); long = long - 5) {
                addMarker(lat, long);
            } //End Long for
        } //End lat For
    } //End function
}

function addMarker(lat, long) {
    _lat = lat;
    _long = long;
    $.ajax({
                    url: 'http://api.openweathermap.org/data/2.5/weather?lat=' + _lat + '&lon=' + _long + '&APPID=' + apiKey,
                    dataType: "json",
                    success: function (data) {
                        new google.maps.Marker({
                            map: map,
                            position: new google.maps.LatLng(_lat, _long),
                        }); //End Marker
                    }, //End Success
                    error: function () {
                        alert("ERROR");
                    }
                }); //End AJAX
}

initialize();

Upvotes: 4

Related Questions