Understanding Reactivity in Meteor using Iron Router and Google Maps

Often Meteor JS can feel like magic.

I’ve been working with Meteor for a few weeks now, and just now grasped the full splendor of Meteor Reactivity. If you are new to Meteor, this is a short read that will give you an “aha!” moment.

Here’s the project I’m working on, it is very simple.

Before the reactive way, was the non-reactive way. It involved about a hundred lines of code dedicated to controlling and managing timer intervals for certain variables whose load times were variable. Those days are gone.

The Reactive Way

In my project/lib/environment.js file I define routes for http://www.coffee-and-wifi.in/ and http://www.coffee-and-wifi.in/bangkok

The hooks (the functions) are reactive – which is awesome because it means that anytime one of the Session variables changes, all functions that use those specific Session variables will re-run.

Since I’m writing this website through a VPN in China, the load speeds for each one of the code blocks below is really variable. The problem here, is that in order for Google Maps to render a map, it needs coordinates for the center of the map (Block #3) . In order to get coordinates for the center of the map, I need to get information from Iron Router about which map to load (Block #2). If I need to load the current location map, I need the current location (Block #1).

Code Block #1 – Navigator

Meteor.startup(function() {

 // get current position
 if (navigator.geolocation) {
   navigator.geolocation.getCurrentPosition(getPosition);
 } else {
   alert("Geolocation is not supported by this browser.");
 }

});

Code Block #2 – Iron Router

Router.route('/', function () {
 Session.set('latitude_center', Session.get('latitude_current'));
 Session.set('longitude_center', Session.get('longitude_current'));
});

Router.route('/bangkok', function (){
 Session.set('latitude_center',13.741943);
 Session.set('longitude_center',100.548653);
});

Code Block #3 – Google Maps

This block involves David Burle’s dburles:google-maps package, which really neatly wraps up the Google Maps API for easy Meteor accessibility.

In the app-maps/client/maps-client.js (I chose to structure my files into subdirectories) I have the helper functions for the template called “map”. Helper functions are by default reactive computations which means that anytime a reactive piece of data (like a Session variable) inside the function changes, the function is re-run. So take a second to look at the code.

Template.map.helpers({
 // This is a helper function, so it is a 'reactive computation'
 // Any time a Session variable inside it changes, the function surrounding it will run again

 exampleMapOptions: function() {

  if(GoogleMaps.loaded()){

  // Map initialization options
   return {
    center: new google.maps.LatLng(Session.get('latitude_center'), Session.get('longitude_center')),
    zoom: Session.get('zoom'),
    mapTypeControl: true,
    navigationControl: true,
    scrollwheel: false
   };
  }
 }
});

The return function causes the Google Map to render. And since the helper function is a reactive computation, whenever the Session variable for ‘latitude_center’ and ‘longitude_center’ change, the center of the map will move accordingly.

Summary

In Block #2 the Session variable for ‘latitude_center’ (center of the map) is set to equal ‘latitude_current’ (current location). Most of the time, when this code is first called, the current location is not yet known. So initially ‘latitude_center’ is undefined. If it stays undefined, no map will load.

In Block #1 the Session variable for ‘latitude_current’ is set. Sometimes it takes the navigator a while to get running. Sometimes Block #3 runs before Block #2 and the map renders as a gray because the values for the center are undefined.

Finally, in Block #3 the map is rendered according to Session variables for the center of the map. If either Block #1 or Block #2 haven’t finished running, the map will be gray. If you pay close attention, you might notice it load gray before quickly changing to a visible map.

The nifty thing, is that it doesn’t matter which order these blocks load. Because they are all linked together with reactive Session variables, each block gets “notified” when it’s time to update.

More Practice

For more practice, check out David Burles’ How to create a reactive Google map in Meteor.

getmii.com getmii getme get me doyougetmii goyougetme need kornukopiarala

Leave a comment