0

The following code grabs some JSON data from /home.json URL which contain 5 microposts by 6 users. However, only the last 4 markers are shown (not even the 5th !!). I have spend 2 days to find the bug but unfortunately I can't really get why this dosen't work. If anyone could help me I would really appreciate it!

I have tested all lon/Lat variables through alert! All of them have the appropriate data. The map should be ok since the last 4 are shown !! Most probably the problem lies with my closure definition but I really cannot understand what I am doing wrong..

var GMAPS = window.GMAPS || {};
GMAPS.mainMap = function() {
  var map;
  var infowindow = new google.maps.InfoWindow();
  var jsonObject = {};

  function addMarkers() {
    var xhr = new XMLHttpRequest();
    xhr.open( "GET", "/home.json", true );
    xhr.onreadystatechange = function () {
      if ( xhr.readyState == 4 && xhr.status == 200 ) {
        jsonObject = JSON.parse( xhr.responseText );
        for (var i=0; i<jsonObject.length; i++) {
          for (var j=0; j<jsonObject[i].microposts.length; j++) {
            (function(Name, Title, Content, Latitude, Longitude) {
              return function() {
                //alert(Name + "\n" + Title + "\n" + Content + "\n" + Latitude + "\n" + Longitude + "\n");  //<-- this works!
                var position = new google.maps.LatLng(Latitude, Longitude);
                var contentString = "<h4>" + Name.bold() + "</h4>" + "<br />" + Title.bold()
                                + "<br />" + Content;

                var marker = new google.maps.Marker({
                  position: position,
                  title: Title,
                  map: map
                });
                google.maps.event.addListener(marker, 'click', (function(marker, contentString) { 
                    return function() { 
                      infowindow.setContent(contentString); 
                      infowindow.open(map, marker); 
                    } 
                })(marker, contentString));
              };
            })(jsonObject[i].name, jsonObject[i].microposts[j].title,
               jsonObject[i].microposts[j].content,
               jsonObject[i].microposts[j].lat,
               jsonObject[i].microposts[j].lon)();
          }
        }
      }
    };
    xhr.send(null);
  }

  function createMap() {
    map = new google.maps.Map(document.getElementById('main_map'), {
      zoom: 10,
      panControl: true,
      zoomControl: true,
      zoomControlOptions: {
        style: google.maps.ZoomControlStyle.SMALL
      },
      mapTypeControl: true,
      scaleControl: true,
      streetViewControl: true,
      overviewMapControl: true,
      scrollwheel: false,
      center: new google.maps.LatLng(37.975327,23.728701),
      mapTypeId: google.maps.MapTypeId.ROADMAP
    });
  }


  function initAddress() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(showPosition);
    }
    else {
      var position = new google.maps.LatLng(0, 0);
      map.setCenter(position);
    }
  }

  function showPosition(position) {
    var position = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
    map.setCenter(position);
  }

  return {

    initMap : function() {
      createMap();
      initAddress();
      addMarkers();
    }
  };
}();

document.addEventListener("DOMContentLoaded", GMAPS.mainMap.initMap, false);
vasilakisfil
  • 2,279
  • 4
  • 24
  • 31

2 Answers2

1

** Note: you have an unnecessary extra set of parens at the end of your IIFE.

Before your IIFE (inside the innermost for-loop), try adding:

var jObj = jsonObject[i], mPost = jObj.microposts[j];

Then in replace the arguments to the IIFE with:

(function(Name, Title, Content, Latitude, Longitude) {
              return function() {
                //alert(Name + "\n" + Title + "\n" + Content + "\n" + Latitude + "\n" + Longitude + "\n");  //<-- this works!
                var position = new google.maps.LatLng(Latitude, Longitude);
                var contentString = "<h4>" + Name.bold() + "</h4>" + "<br />" + Title.bold()
                                + "<br />" + Content;

                var marker = new google.maps.Marker({
                  position: position,
                  title: Title,
                  map: map
                });
                google.maps.event.addListener(marker, 'click', (function(marker, contentString) { 
                    return function() { 
                      infowindow.setContent(contentString); 
                      infowindow.open(map, marker); 
                    } 
                })(marker, contentString));
              };
            })(jObj.name, mPost.title, mPost.content, mPost.lat, mPost.lon);
Joe Johnson
  • 1,814
  • 16
  • 20
  • Thank you for your answer Joe. I have the extra parens in order to invoke my inner anonymous function. If I remove them then no markers are shown. Unfortunately, your solution is not working (no markers are shown). Again if I add the extra parens only the last 4 markers are shown.Perhaps you could explain me what I am doing wrong and on which logic you based your suggestions ? Maybe that will help me to solve my problem :-) – vasilakisfil Nov 29 '12 at 20:43
  • It would be easier if you had somewhere I could see this code execute... with actual data. – Joe Johnson Nov 29 '12 at 20:55
  • Actually, can you just copy/paste the jsonObject here? – Joe Johnson Nov 29 '12 at 20:56
  • Thank you again for your interest! I have pasted html code [here](http://pastebin.com/GbRGgweD) and json data [here](http://pastebin.com/F9KMZ2if). I hope these help. However if you want something else please tell me! – vasilakisfil Nov 29 '12 at 21:18
  • Thanks... looking at it now. I posted another answer (for the sake of clarity) already. – Joe Johnson Nov 29 '12 at 21:20
  • Also, I'm not sure why you're returning a function (2nd line in above code) -- as opposed to just executing it (by removing the return function(){} statement). Doesn't make any sense to me... – Joe Johnson Nov 29 '12 at 21:41
0

The following code should work. I still don't understand why you have the extra set of parentheses.

xhr.onreadystatechange = function() {
  var i = 0, j = 0;
  if ( xhr.readyState == 4 && xhr.status == 200 ) {
    jsonObject = JSON.parse( xhr.responseText );
    for (var ilen = jsonObject.length; i < ilen;) {
      for (var jObj = jsonObject[i++], jlen = jObj.microposts.length; j < jlen;) {
        var mPost = jObj.microposts[j++];
        (function(Name, Title, Content, Latitude, Longitude) {
          return function() {
            //alert(Name + "\n" + Title + "\n" + Content + "\n" + Latitude + "\n" + Longitude + "\n");  //<-- this works!
            var position = new google.maps.LatLng(Latitude, Longitude);
            var contentString = "<h4>" + Name.bold() + "</h4>" + "<br />" + Title.bold()
                            + "<br />" + Content;

            var marker = new google.maps.Marker({
              position: position,
              title: Title,
              map: map
            });
            google.maps.event.addListener(marker, 'click', (function(marker, contentString) { 
                return function() { 
                  infowindow.setContent(contentString); 
                  infowindow.open(map, marker); 
                } 
            })(marker, contentString));
          };
        })(
          jObj.name, mPost.title, mPost.content, mPost.lat, mPost.lon
        );
      }
    }
  }
};
Joe Johnson
  • 1,814
  • 16
  • 20