Meteor.js is a new(ish) platform that is gaining popularity due to the fact that is an allows for the building of isomorphic JavaScript web applications. If you don't know what that means, let me enlighten you from the google search I had to do to find out. An isomorphic web application can run both client-side and server-side which means they can share the same code. For those of us who are used to segretating our client-side code from our server-side code and using something like AngularJS for the front-end and Node.js and Express for the server, Meteor sort of muddies that all up. The first thing you realize when you install meteor and start one of their simple example web apps is that this distinction between server-side and client-side is blurred. For sure, you still have server-side and client-side (how could you not given that a user on a browser is still sending requests to a server) but your development of the web app will no longer have such clear-cut distinctions in your code.

Getting used to Meteor.methods

Meteor.methods are server methods that can be called by the client. For instance, you could set up the CommentOnPost method on the server that in the 'do stuff' section would interact with the Mongo database (Meteor ships with mini-Mongo that makes it super easy to quickly create and interact with Mongo collections)

// On the server
Meteor.methods({
  commentOnPost: function (comment, postId) {
    // Check argument types
    check(comment, String);
    check(postId, String);

    if (! this.userId) {
      throw new Meteor.Error("not-logged-in",
        "Must be logged in to post a comment.");
    }

    // ... do stuff ...

    return "something";
  },

  otherMethod: function () {
    // ... do other stuff ...
  }
});

On the client side, instead of setting up traditional HTTP requests to interact with the database, you simply have to call your meteor method like so:

    // Asynchronous call with a callback on the client
Meteor.call('commentOnPost', comment, postId, function (error, result) {
  if (error) {
    // handle error
  } else {
    // examine result
  }
});

And just like magic, the request is sent without you having to worry about how.
However, you still have to think about routing so that your app loads the appropriate template. This is where Meteor's Iron Router comes in.

Templates and Iron Router

Let's take a simple example to undertand how we can use Iron Router in our app. Our example app will be a card game app with card rooms for distinct games. As such, we will want to make sure that when a user clicks to join a room that we have routing set up to make sure that they enter the correct room. On the server side what this means is that the user gets added to a Mongo "Room" collection that has been defined. The "Room" is identified by a unique i.d. which gets created automatically by Mongo when the room gets created (in Mongo, this will be a document within our "Room" collection).

From the home page, when a user clicks on a button to join a room, we need a way to route them to that room. One way to set this up would be the following:

<a class="joinExistingRoom" href="{{pathFor route='chatRoom' data=roomId}}">Room</a>

Here I'm using an anchor tag to create a button. The interesting part here is in the href property where we use the Iron Router pathFor to route to a route we've created called room. The data property was used to populate a list of 'rooms' with the unique room id (I haven't shown it here but the anchor tag is actually within an unordered list). An array of data which contains room objects is iterated over and the values for the key roomId extracted. You will see next how that roomId is provided to Iron Router to create a unique. In a file I call router.js, we will set up a basic route for the rooms.

    Router.route('/room/:room', {
  // this template will be rendered until the subscriptions are ready
  loadingTemplate: 'layout',
  data: function () {
    var data = Room.findOne({_id: this.params.room});
    return data;
  },
  action: function () {
    console.log(123);
    this.render('room', {to: 'show'});
  },
  name: 'chatRoom'
});

Let me break this down. We are setting up a route that might look like this /room/fg3fkaldke where the last part of the path after the / is our room id number that was created by Mongo when the room was created in the "Room" collection. loadingTemplate is the template that renders before our data comes back from the server for the room. data is a method that queries the database to find the room with an id that we get from the parameter we are passing in the url, which is gotten with this.params.room. The waitOn method tells the template that will load when the data comes back from the server - in this called the template is called 'room'. this.render('room', {to: 'show'}); means to render the 'room' template (into the layout template that has already rendered) when the data comes back from the server. name: 'chatRoom' uniquely identifies this route (and all the associated logic) and is used in our anchor tag above in pathFor route='chatRoom'. You don't need to create a name and Iron Router will guess based on the route, in this case '/room', but I think it removes ambiguity and is probably a good practice.

So now when someone clicks on the button (anchor tag) on our home page, it will take them to a unique chat room with the url like this /room/fg3fkaldke.

How to create a list of rooms that point to unique rooms

The last thing I want to cover takes us back to the anchor tag we created on the home page. I mentioned that depending on however many rooms are in the "Room" collection in the Mongo database, we could populate a list and users could click on and enter those rooms. Here's how we are accomplishing that here.

Here's what more of the code looks like in our home.html template file. This file is loaded into the layout.html file when the home page renders:

<ul>
    {{#each loadRooms}}
    <li>
      <a class="join-room" href="{{pathFor route='chatRoom' data=room}}">Room</a>
    </li>
    {{/each}}
 </ul>

If you are new to Meteor, the {{#each loadRooms}} will look strange, but maybe not so strange if you've used Handlebars before. Load rooms is a helper method that is loaded when the template loads and is defined in Template..helpers which in this case resides in a file I've called home.js. This helper method queries the "Room" collection for all the rooms and returns a list of them. The #each is like a for loop that iterates over the returned array and pulls out the room id's. This interacts with the Iron Router and together the list of rooms is created with unique urls that represent the room ids.

I hope this will help you set up routes with Iron Router and cut down your development time.