Triple Click Studio Triple Click Studio - 1 month ago 10
jQuery Question

JSON feed on Google map is showing nothing

I want the Google map show marker with JSON feeds. but it's not working. I can't find the actual problem. so here is my code:



var map;

// The JSON data
var json = [{
"OpperationErrorMsg":"",
"IsSuccess":true,
"ResultId":1000,
"Timestamp":"2016-10-12T18:00:07.0232702Z",
"Echo":null,
"InSandbox":true,
"DebugMessages":[

],
"MissingDetails":[

],
"ResponseData":[
{
"CallTimeLocal":"2016-10-10T06:28:48.7330000",
"IncidentId":3374,
"IncidentNumber":"HC2016004034",
"CallTime":"2016-10-10T10:28:48.7330000",
"ElapsedSeconds":0,
"Location":"2712 E HANNA AVE",
"BuildingName":null,
"BuildingNumber":null,
"NatureId":6743,
"FirePriorityId":1,
"CoordinateX":-82.429500000000,
"CoordinateY":28.003389000000
},
{
"CallTimeLocal":"2016-10-10T11:28:36.7000000",
"IncidentId":3382,
"IncidentNumber":"HC2016004042",
"CallTime":"2016-10-10T15:28:36.7000000",
"ElapsedSeconds":0,
"Location":"1220 APOLLO BEACH BLVD S",
"BuildingName":"Apollo Beach Marina",
"BuildingNumber":null,
"NatureId":8035,
"FirePriorityId":1,
"CoordinateX":-82.422369000000,
"CoordinateY":27.781254000000
},
{
"CallTimeLocal":"2016-10-10T14:29:59.8830000",
"IncidentId":3387,
"IncidentNumber":"HC2016004047",
"CallTime":"2016-10-10T18:29:59.8830000",
"ElapsedSeconds":0,
"Location":"9600 SHELDONWOOD RD",
"BuildingName":null,
"BuildingNumber":null,
"NatureId":6420,
"FirePriorityId":12,
"CoordinateX":-82.580530000000,
"CoordinateY":28.034779000000
},
{
"CallTimeLocal":"2016-10-10T15:27:37.7270000",
"IncidentId":3389,
"IncidentNumber":"HC2016004049",
"CallTime":"2016-10-10T19:27:37.7270000",
"ElapsedSeconds":0,
"Location":"4691 GALLAGHER RD",
"BuildingName":"Strawberry Crest High School",
"BuildingNumber":null,
"NatureId":7873,
"FirePriorityId":2,
"CoordinateX":-82.236450000000,
"CoordinateY":28.021233000000
}
],
"CurrentStatusData":null
}];



function initialize() {

// Giving the map som options
var mapOptions = {
zoom: 6,
center: new google.maps.LatLng(25.0,-80.0)
};

// Creating the map
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);


// Looping through all the entries from the JSON data
for(var i = 0; i < json.length; i++) {

// Current object
var obj = json[i];

// Adding a new marker for the object
var marker = new google.maps.Marker({
position: new google.maps.LatLng(obj.CoordinateY,obj.CoordinateX),
map: map,
draggable: true,
animation: google.maps.Animation.DROP,

title: obj.BuildingName // this works, giving the marker a title with the correct title
});

// Adding a new info window for the object
var clicker = addClicker(marker, obj.title);

} // end loop


// Adding a new click event listener for the object
function addClicker(marker, content) {
google.maps.event.addListener(marker, 'click', function() {

if (infowindow) {infowindow.close();}
infowindow = new google.maps.InfoWindow({content: content});
infowindow.open(map, marker);

});
}

}

// Initialize the map
google.maps.event.addDomListener(window, 'load', initialize);

html, body, #map-canvas {
height: 100%;
margin: 0;
padding: 0;
}

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true"></script>
<script src="https:////cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div id="map-canvas"></div>





I will be using it on a HTML page. Though the JSON data will be updated automatically so i can't change the JSON Arrays.

Thanks!

Answer

I found these problems in your code:

  • In your loop where you create each marker, you are looping over the json array. However, this is not your array of marker data. json[0] is your main object, and json[0].ResponseData is the marker array that you need to loop over. So I put that value in a variable named responses and looped over that instead. I don't know if the JSON data could have more than one object in its outermost array; if it does you would need an outer loop to handle those. For now I assumed there is just one outer object addressed with json[0].
  • When you call addClicker you pass in obj.title which doesn't exist. Presumably you meant obj.BuildingName.
  • Your click handler references a variable called infowindow, but on the first click that variable does not exist and causes an error. So I declared infowindow as a global window.

So, how did I find these problems? Using the JavaScript debugger. Normally I would add a debugger; statement at the beginning of the initialize() function and single step through the code to see what is going on. This would reveal that where the main loop sets var obj = json[i]; it isn't getting the expected value.

That works great on a normal web page, but it doesn't seem to work well in the embedded snippet here on SO. (The debugger shows the wrong source line.) So instead I started adding console.log(); statements where it looked like things might be going wrong, such as console.log( 'obj:', obj ); immediately after the var obj = assignment.

Also, it's nice to automatically zoom and center the map according to where the markers are located. I added a bit of code using a LatLngBounds which is extended for each marker, and then a map.fitBounds() after all the markers are created. If you do that you don't need to explicitly zoom and center the map when first creating it, so I removed those. (Otherwise the map is displayed at one position and then repositioned.)

One caveat with the fitBounds(): if there were no markers, then the map wouldn't get displayed at all. To handle that case you would want to check for the case where responses.length is zero and call map.setZoom() and map.setCenter() with default values.

I marked the changed lines with //// to make them easy to find:

 var map, infowindow; ////

// The JSON data
var json = [{  
   "OpperationErrorMsg":"",
   "IsSuccess":true,
   "ResultId":1000,
   "Timestamp":"2016-10-12T18:00:07.0232702Z",
   "Echo":null,
   "InSandbox":true,
   "DebugMessages":[  

   ],
   "MissingDetails":[  

   ],
   "ResponseData":[  
      {  
         "CallTimeLocal":"2016-10-10T06:28:48.7330000",
         "IncidentId":3374,
         "IncidentNumber":"HC2016004034",
         "CallTime":"2016-10-10T10:28:48.7330000",
         "ElapsedSeconds":0,
         "Location":"2712 E HANNA AVE",
         "BuildingName":null,
         "BuildingNumber":null,
         "NatureId":6743,
         "FirePriorityId":1,
         "CoordinateX":-82.429500000000,
         "CoordinateY":28.003389000000
      },
      {  
         "CallTimeLocal":"2016-10-10T11:28:36.7000000",
         "IncidentId":3382,
         "IncidentNumber":"HC2016004042",
         "CallTime":"2016-10-10T15:28:36.7000000",
         "ElapsedSeconds":0,
         "Location":"1220 APOLLO BEACH BLVD S",
         "BuildingName":"Apollo Beach Marina",
         "BuildingNumber":null,
         "NatureId":8035,
         "FirePriorityId":1,
         "CoordinateX":-82.422369000000,
         "CoordinateY":27.781254000000
      },
      {  
         "CallTimeLocal":"2016-10-10T14:29:59.8830000",
         "IncidentId":3387,
         "IncidentNumber":"HC2016004047",
         "CallTime":"2016-10-10T18:29:59.8830000",
         "ElapsedSeconds":0,
         "Location":"9600 SHELDONWOOD RD",
         "BuildingName":null,
         "BuildingNumber":null,
         "NatureId":6420,
         "FirePriorityId":12,
         "CoordinateX":-82.580530000000,
         "CoordinateY":28.034779000000
      },
      {  
         "CallTimeLocal":"2016-10-10T15:27:37.7270000",
         "IncidentId":3389,
         "IncidentNumber":"HC2016004049",
         "CallTime":"2016-10-10T19:27:37.7270000",
         "ElapsedSeconds":0,
         "Location":"4691 GALLAGHER RD",
         "BuildingName":"Strawberry Crest High School",
         "BuildingNumber":null,
         "NatureId":7873,
         "FirePriorityId":2,
         "CoordinateX":-82.236450000000,
         "CoordinateY":28.021233000000
      }
   ],
   "CurrentStatusData":null
}];

function initialize() {
  
  // Giving the map som options
  var mapOptions = {
    ////
  };
  
  // Creating the map
  map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
  
  var bounds = new google.maps.LatLngBounds(); ////
  
  // Looping through all the entries from the JSON data
  var responses = json[0].ResponseData; ////
  for(var i = 0; i < responses.length; i++) { ////
    
    // Current object
    var obj = responses[i]; ////

    // Adding a new marker for the object
    var position =
      new google.maps.LatLng( obj.CoordinateY, obj.CoordinateX ); ////
    bounds.extend( position ); ////
    var marker = new google.maps.Marker({
      position: position, ////
      map: map,
      draggable: true,
      animation: google.maps.Animation.DROP,
      title: obj.BuildingName
    });
    
    // Adding a new info window for the object
    var clicker = addClicker(marker, obj.BuildingName); ////

  } // end loop
  
  map.fitBounds( bounds ); ////
  
  // Adding a new click event listener for the object
  function addClicker(marker, content) {
    google.maps.event.addListener(marker, 'click', function() {
      
      if (infowindow) {infowindow.close();}
      infowindow = new google.maps.InfoWindow({content: content});
      infowindow.open(map, marker);
      
    });
  }
  
}

// Initialize the map
google.maps.event.addDomListener(window, 'load', initialize);
html, body, #map-canvas {
  height: 100%;
  margin: 0;
  padding: 0;
}
 <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?v=3.exp&sensor=true"></script>
   <script src="https:////cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<div id="map-canvas"></div>