Meteor Capture

How to create a reactive Google map

When using Google maps with Meteor you may wish to make use of Meteor's reactivity and do something fancy such as displaying markers and other things in real-time.

However it can be tricky to wrangle the maps API into something that works reactively, so we're going to step through an example project that demonstrates an approach we can begin with.

I've written a popular package that assists with both loading and interacting with map instances. To begin, add it to your project:

meteor add dburles:google-maps

If you wish, you can view and clone the completed version of the example here:

Step 1.

First up, let's create a template to display the map as well as some CSS for containing the map.

<template name="map">  
  <div class="map-container">
    {{> googleMap name="map" options=mapOptions}}
.map-container {
  width: 100%;
  max-width: 100%;
  height: 500px;

Step 2.

Great. So next up we want to load the API and pass some options to the map.

Meteor.startup(function() {  
  mapOptions: function() {
    if (GoogleMaps.loaded()) {
      return {
        center: new google.maps.LatLng(-37.8136, 144.9631),
        zoom: 8

If all has gone well you should now see a map centered over Melbourne, Australia.

Step 3.

Now we're going to get into the fun part. Add the following to your project: {  
  GoogleMaps.ready('map', function(map) {
     console.log("I'm ready!");

This callback is tied into the tilesloaded event as part of the Google Maps API. We will interact with the API within the GoogleMaps.ready callback.

The callback can live almost anywhere, but it's good practise to contain it within the containing template onCreated callback as we may wish to access the template instance and data context.

Go ahead and save, you should see "I'm ready" in the browser console.

Step 4.

Now for the actual fun part. Create a collection in order to store some map marker coordinates.

Markers = new Mongo.Collection('markers');  

Step 5.

Add an event listener within the ready callback. This will insert the coordinates into the markers collection where the map was clicked. {  
  GoogleMaps.ready('map', function(map) {
    google.maps.event.addListener(map.instance, 'click', function(event) {
      Markers.insert({ lat:, lng: event.latLng.lng() });

    // The code shown below goes here


Step 6.

Now it's time to make things reactive!

var markers = {};

  added: function(document) {
    // Create a marker for this document
    var marker = new google.maps.Marker({
      draggable: true,
      animation: google.maps.Animation.DROP,
      position: new google.maps.LatLng(, document.lng),
      map: map.instance,
      // We store the document _id on the marker in order 
      // to update the document within the 'dragend' event below.
      id: document._id

    // This listener lets us drag markers on the map and update their corresponding document.
    google.maps.event.addListener(marker, 'dragend', function(event) {
      Markers.update(, { $set: { lat:, lng: event.latLng.lng() }});

    // Store this marker instance within the markers object.
    markers[document._id] = marker;
  changed: function(newDocument, oldDocument) {
    markers[newDocument._id].setPosition({ lat:, lng: newDocument.lng });
  removed: function(oldDocument) {
    // Remove the marker from the map

    // Clear the event listener

    // Remove the reference to this marker instance
    delete markers[oldDocument._id];

That's quite a chunk of code, so let's go over what's happening.

We've defined an empty object literal called markers that gives us a place to store and reference each Google Maps marker instance.

Next up we're observing changes to the query cursor Markers.find(). This allows us to react when things change.

You may have noticed I've written comments on the code above which hopefully explain things in more detail.


You should now be able to click the map to drop a map marker as well as drag them around to change position. What's great of course is that these actions are shared with anyone else who happens to be viewing the map!


Google Maps package

Gitter chat

If you're after some help or would just like to say hello

The example application

Google Maps Javascript API

comments powered by Disqus