Adding Multiple Markers to Google Maps from JSON
Recently I’ve been receiving several emails from readers of my book, Beginning Google Maps API 3, that has a problem adding information to multiple InfoWindows when loading markers dynamically via JSON data.
In my book I have in fact described how to add multiple markers from JSON and how to attach unique InfoWindows to each of them. What I haven’t described is how to get the JSON-data to actually show up in the InfoWindows. This tutorial aims to describe how to do just that.
The JSON
In this example I’m going to use the capitals of the Scandinavian countries: Stockholm, Oslo and Copenhagen. Each capital will be displayed on the map with a marker. When you click a marker an InfoWindow will popup with some brief information about the city.
The JSON data looks like this:
var json = [
{
"title": "Stockholm",
"lat": 59.3,
"lng": 18.1,
"description": "Stockholm is the capital and the largest city of Sweden and constitutes the most populated urban area in Scandinavia with a population of 2.1 million in the metropolitan area (2010)"
},
{
"title": "Oslo",
"lat": 59.9,
"lng": 10.8,
"description": "Oslo is a municipality, and the capital and most populous city of Norway with a metropolitan population of 1,442,318 (as of 2010)."
},
{
"title": "Copenhagen",
"lat": 55.7,
"lng": 12.6,
"description": "Copenhagen is the capital of Denmark and its most populous city, with a metropolitan population of 1,931,467 (as of 1 January 2012)."
}
]
Note that the JSON data above contains the following information:
- A Title in plain text
We will use this information for a tooltip on the marker - A Latitude
For the latitude portion of the position - A Longitude
For the longitude portion of the position - A Description
The content that will be displayed in the InfoWindows. I’ve included some HTML in it to illustrate that you’re not restricted to just plain text.
Note: In this example I have the JSON data in the same js file as the code, but in a real-life scenario you would probably grab it from an external source such as a back-end server or a web service.
Creating the map
First of all we need to create a map. The map will be centered over Scandinavia so that both Stockholm, Oslo and Copenhagen are visible.
// Creating a new map
var map = new google.maps.Map(document.getElementById("map"), {
center: new google.maps.LatLng(57.9, 14.6),
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
});
If you feel unsure how this all works I recommend that you read Google Maps API 3 – The basics. It describes how to create a simple map.
Adding Markers
To create markers from the JSON-data we need to loop through it and extract the information for each marker.
for (var i = 0, length = json.length; i < length; i++) {
var data = json[i],
latLng = new google.maps.LatLng(data.lat, data.lng);
// Creating a marker and putting it on the map
var marker = new google.maps.Marker({
position: latLng,
map: map,
title: data.title
});
}
This will add markers to the map and they will all have their own unique title which will show up as a tooltip when you hover over them with the mouse.
Adding InfoWindows
Ok, so now we've created a map and added some markers from JSON data. So far it hasn't been that hard, the way of doing this is pretty straight-forward. But to attach the InfoWindows properly is a different story. It's now that it starts to get tricky.
First of all We're going to create a global InfoWindow that we will reuse for all markers. This needs to be created outside of the loop. So just above the loop in the code we insert:
var infoWindow = new google.maps.InfoWindow();
This gives us an empty InfoWindow object that we can use on the map.
The next step is to attach a click event to each marker. In the code that executes we will fill the InfoWindow with the correct information and open it att the right location, pointing at the clicked marker.
At first glance it seems that you can do this the same way that you add markers:
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
The problem with this approach is that when you're trying to add more than one InfoWindow, they will all have the same content as the one in the last iteration. To prevent this from happening we need to use something called a closure.
Closures
What a closure does is to persist the data in each iteration of the loop so that it's bound to that particular marker.
One way of doing this is by encapsulating the code inside an anonymous function that is instantly executed. You need to make sure to pass the information from the current iteration to the anonymous function. In our case we're going to pass the current marker and the current data.
This is kind of a confusing concept and a bit hard to explain, so lets instead look at some code.
Implementing the closure
// Creating a closure to retain the correct data
//Note how I pass the current data in the loop into the closure (marker, data)
(function(marker, data) {
// Attaching a click event to the current marker
google.maps.event.addListener(marker, "click", function(e) {
infoWindow.setContent(data.description);
infoWindow.open(map, marker);
});
})(marker, data);
By passing the data to the anonymous function we make sure that it will stay there. We're essentially creating 3 self contained objects (closures) from our 3 locations.
Now if we're try the code, it will work perfectly and each InfoWindow will display the right information.
Tip: Nicholas Johnson explains how closures work in 5 easy bullet points in his short post, What is it with Closure?
Live Demo
Conclusion
I hope that this example will clear out some confusion on this topic. Closures are a pretty confusing concept but once you understand how it works, it's something you we'll easily be able to apply in your own code. Anyway, you should be able to grab the code from this example and use it as a boilerplate to tweak your own needs.
Happy Coding!
My Google Maps book
If you found this article useful you might be interested in my book Beginning Google Maps API 3. It covers everything you need to know to create awesome maps on your web sites. Buy it on Amazon.com

Pingback: Anyone using the new version of Mapstraction? | Marion Walton
Pingback: Great Expectations