Meteor Js – Build Apps Lightning Fast

Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page

Meteor Js tutorial

In this post, we will see how we can leverage the power of Meteor js to build top quality apps at lightning pace. We will take a quick look at how the framework works and how we can leverage it to build apps easily.

By the end of this post, we will be building 2 apps. A Single Page Chat Application (SPA)  only with Meteor js to get a feel of Meteor & a Multi Page Application (MPA) named Events Feed, leveraging Meteorite js – a package manager for Meteor js & Iron router, that will serve the purpose of a Chat app at live public events.

Chat Application : Live URL

Screen Shot 2014-04-16 at 9.40.30 am

Events Feed: Live URL

Screen Shot 2014-04-16 at 9.42.31 am Screen Shot 2014-04-16 at 9.42.41 am Screen Shot 2014-04-16 at 9.43.33 am

So lets get started.

Contents

What is Meteor js

Meteor is an open-source platform for building top-quality web apps in a fraction of the time, whether you’re an expert developer or just getting started.

The key difference between Meteor js and other frameworks like Angularjs or Backbone is that, Meteor js uses a DDP (Data Distribution Protocol) for its client server communication, unlike Angularjs or Backbonejs which rely on REST endpoints for serving data from server & keeping it in sync with the client.

What does this mean? This means that as Javascript developers we need not worry about how the data travels between server and client, if they are in sync etc. but rather concentrate on more important things like the actual business logic.

Seven Principles of Meteor

There are 7 Key principles listed by Meteor on why to use Meteor js.

  • Data on the Wire. Don’t send HTML over the network. Send data and let the client decide how to render it.
  • One Language. Write both the client and the server parts of your interface in JavaScript.
  • Database Everywhere. Use the same transparent API to access your database from the client or the server.
  • Latency Compensation. On the client, use prefetching and model simulation to make it look like you have a zero-latency connection to the database.
  • Full Stack Reactivity. Make realtime the default. All layers, from database to template, should make an event-driven interface available.
  • Embrace the Ecosystem. Meteor is open source and integrates, rather than replaces, existing open source tools and frameworks.
  • Simplicity Equals Productivity. The best way to make something seem simple is to have it actually be simple. Accomplish this through clean, classically beautiful APIs.

Setup Meteor

Meteor js supports only Linux and Mac OS X as development and deployment environments. For Windows, the solution is a VM. You can read more here.

Windows users, You can follow the VM approach to setup and continue from here, Mac/Linux users, you can dig right in.

Open terminal and run

curl https://install.meteor.com | /bin/sh

This will install Meteor.

Create & Run a Chat App

To get a feel of Meteor js, we will first write a simple single page Chat application. Create a new folder name myMeteorApps. We will be scaffolding a new Meteor app here

cd myMeteorApps

meteor create chatApp

A new project will be scaffolded. Let’s run the app as is and see the output. Run

cd chatApp && meteor

When we downloaded Meteor js a copy of MongoDB was also downloaded. And when we run   meteor the local instance of MongoDB will be started (We will take a look at MongoDB soon).

Navigate to  http://localhost:3000/  in your favorite browser, and you should see something like

Screen Shot 2014-04-13 at 10.06.14 pm

Open up the dev tools and navigate to the console tab and click on the button above & you will see a message logged like You pressed the button.

Understanding Project Structure

Now, Lets take a look at the project structure. When you open up the chatApp folder, you will see

Screen Shot 2014-04-13 at 10.09.00 pmDarn the simplicity!! An Awesome frameworks with 3 files and a hidden folder?? Really? Loved it when I saw this for the first time!

Let’s quickly go through the resources.

.meteor folder : DO NOT mess with this folder. This folder consists of

Screen Shot 2014-04-13 at 10.14.25 pm

MongoDB configs, Project builds, release details etc. This is where all the magic actually happens.

chatApp.js : This is the heart of our application. Meteor loads up this file on both the server and client. If you open the file in your favorite editor, you will see 

Whatever code snippets are present inside Meteor.isServer , will be executed on the server side and   Meteor.isClient will be executed on the client side. If the code isn’t surrounded by either conditions, it will loaded in both the server & client (ex: A Date Util function). So, this way, a piece of code can be shared between both the server and client.

Lets take a quick peek inside the js file.

Line 2 : Below are the guts of the Template object

Screen Shot 2014-04-13 at 10.23.59 pm

The Template object stores all our templates on the page and we can access the template via a dot notation followed by the template name. In this case hello. Then we are dynamically creating a new function, where we are storing some data. This will be injected into the Handlebars expressions.

For starters, you can change the message from “Welcome to chatApp”  to “This is awesome” Save it and go back to the browser – No need to refresh, Meteor will do that for you. Simple & Sweet right?

Line 6 : Events is another property of the Template. Template stores events related to only that template. The syntax to register an event is a JSON. The Key will be the event followed by space followed by the selector and the value is a function or rather an event handler.

Do note that if there was another template with an input element inside, this event will not be fired.

chatApp.html :  Meteor builds all its markup using Handlebar templates. A simple and easy to use templating engine. You can read more about it here.

If you open up chatApp.html, you will see

Line 6 : This is the syntax to render the hello template at this DOM location

Line 11 : This is where the Template.hello.greeting() will kick in to provide a value.

PS : Do note that all the templates are written outside the body.

PS : Did you notice that we did not write the script tag or link tag to load the resources? Meteor does this for us.

This folder structure is good for a small app. What if you want to build a huge application where you want to maintain multiple js files for the server & client,  a scenario where a single file is dependent on many other files and you do not want to keep writing Meteor.isClient or Meteor.isServer for every code block?

Well, Meteor has a solution.

Structuring our Application

Modular Folder Structure

  • 1. You can create a new folder at the root named client and put all your client related files here
  • 2. You can create a new folder at the root named server and put all your server related files here
  • 3. You can create a new folder at the root named public to store static files like images and fonts. You can refer it directly as logo.png in your html. 
  • 4. You can create a new folder at the root named lib and put all your third party related js here

Order of Loading

Okay, we have seen that we are not specifying the js and css import in our mark up & Meteor is doing this for us. But with so many js files split across so many folders, how will Meteor know which file to load when? Well, there are a few rules

  • 1. Files in the lib folder will be loaded first (Duh!)
  • 2. Depending on the location of a file in the directory/sub-directories, the deepest file will be loaded first.
  • 3. If there are many files in one folder, they are loaded alphabetically.
  • 4. Then the server folder files are loaded and finally the client folder files are loaded.

Refactor our Application

Simple right? Now lets refractor our project to make things more clear.

  • 1. Create a new folder named server at the root & create a new file named server.js here.
  • 2. Create a new folder named client at the root & create a new file named client.js here.
  • 3. Copy all the content inside the Meteor.isClient block to client.js
  • 4. Copy all the content inside the Meteor.isServer block to server.js
  • 5. Delete the chatApp.js

And your folder structure should be

Screen Shot 2014-04-13 at 11.10.16 pm

You can go back to the browser and refresh the page, the output will still be the same.

Meteor Packages

To the meat of Meteor. This is the real power of Meteor that makes building large apps lightning fast. Meteor come out of box with the most essential packages needed for today’s web development. To view a list of packages that come with Meteor, run

meteor list

And you should see something like

Screen Shot 2014-04-14 at 10.07.16 amWe will soon discuss about Meteorite, which is the Package and Version manager for Meteor. But for this chat app, lets use Meteor’s core packages to get things done.

Continue Development

Now, lets get back to the project at hand. To make our app look good, let’s add Bootstrap to our project. Back to terminal (you can open a new terminal tab here & continue, as we will be making live changes and letting Meteor take care of refreshing), run

meteor add bootstrap

Now, refresh the app and you should Bootstrap look kick in. Do note that the Meteor Bootstrap package uses Bootstrap v2.3.0. We will leverage Meteorite to get a Bootstrap v3 for our other project.

Application Logic

A user will enter his name and a message and submit the post. We will take that message and save it in the database. And the Meteor’s DDP will synchronize all its clients with same post.

Sounds simple? It’s even easy to implement using Meteor.

Code the App

Open up chatApp.html. We will update the hello template to show a welcome message to the user and the updated hello template would be

Back to the page in browser and you should see the updated UI. Next lets have a template to show all the messages that are entered by users. The messages template will be like

And then finally we need a template where a user can enter his name and a message and send it. Lets call this the input templates. This will contain 2 text boxes, one for entering the name & the other for the message.

The updated chatApp.html will be like

Back to the page & the updated UI would look like

Screen Shot 2014-04-14 at 7.49.40 pm

Now, for the server side. We will create a new collection called Messages to store a list of messages sent by the users, along with their name. Remove everything from server.js and add the following line

Messages = new Meteor.Collection('messages');

This is all we need to create a new Database collection to store our messages. Meteor will take care of the remaining details for us.

Next, lets add a logic to our client side to show the list of messages that are present in the DB. Again, Meteor will take care of the sync when some new data is pushed to the DB. The updated client.js will be like

Line 1 : Since we do not have any js file that is in the root folder, we will replicate messages collection in client.js as well. If you don’t want, you can create a new file named collections.js at the root of the project and push all your collections there, this will be loaded on both server and client and you need not replicate it like above. I have done this to create a demarcation between server and client

Line 3 : We will query the messages collection and display the list of messages here.

Back to the page and you should not see any change, because we do not have any data in our collection. Meteor provides an insecure package, where you can query the DB from console. Yep! Javascript console. If you are making the app production ready, do not forget to remove this package using

meteor remove insecure

Now, the fun part, back to our page and open the dev tools. And execute the following line in the console

Messages.insert({name: "Arvind", message: "Hello All", time: Date.now()});

And by the time you say Send Data, you will see

Screen Shot 2014-04-14 at 8.07.03 pm

Just for fun, open another tab/browser and open the same URL, you should see the same messages listed. Play around to see how data syncs up. You can open the network tab in dev tools to see the requests that are fired.

Now, lets add the functionality to the send button. When a user enters his name, a message and submits, we will save this data to the collection.

So, our updated client.js will be

And you can open 2 browsers/tabs and check this  out

Screen Shot 2014-04-14 at 8.18.36 pmNow, What do you say if we integrated our app with third party authentication like Twitter or GitHub or Facebook, so that instead of user entering his name, we will pull it up. And also, lets not allow the “not logged in” users to participate in chat.

How long do you think this is going to take? 3 to 4 hours? Well with Meteor this will take around 10 mins. And this is how.

Back to the terminal, (where the meteor is not running) and lets add a accounts-ui package to provide us templates to add login widgets to an app. Then we will add accounts-github package to integrate Login service for Github accounts (You can add any other package as you wish. You can check the list by running meteor list ). Run

meteor add accounts-ui

next

meteor add accounts-github

Thats it, the required packages are added to our app. Bam!! now all we need to do is add

 {{> loginButtons}}

to our page, where you want to see the login button. So, our updated chatApp.html will be

Back to the web page and you should see something like

Screen Shot 2014-04-14 at 8.48.53 pm

And when you click on the Configure GitHub Login button, you will see a list of instructions to set up the account. You can follow those instructions and fill in the Client ID & Client Secret.

This process is same for any accounts-*  packages. Once that is done, you can login with your GitHub ID.

You need not worry about login management or token exchange, Meteor will take care of it for you. Once you login. you should see you user name on top right corner.

Now, lets update our app to take the login name from the session & the updated chatApp.html will be

On line 10, we check if the currentUser is null. If it is, we will not show the input template. If there is an active login present, Meteor will populate this variable with the user object.

If you curious to know what’s inside it, you can always use a Handlebar helper to print out the object. You can add this to you client.js

And in your chatApp.html add the following line

{{logMe currentUser}}

And you can see the object in console

Screen Shot 2014-04-15 at 9.36.04 am

You can use the above technique to debug objects that are passed to Handlebars.

Now, we need to updated our client.js, to take the value of name from the user(). The updated client.js will be

On line 13, we are fetching the value of the logged in user. This is the exact same object as currentUser. This will be null if there is no user logged in.

And our final output would be

Screen Shot 2014-04-15 at 9.44.24 am Screen Shot 2014-04-15 at 9.44.42 amIf you are feeling adventurous, you can open up the dev tools and start analysing the js files that were loaded & also view the source of the page, you will be a bit surprised.

MongoDB

Everything is awesome, cool, easy to build. But what is actually happening to the data? Where is it being stored? What if you noticed that your ex has registered with app and want to know what they are up to?

Well, all the data is stored in MongoDB for us, which is installed as part of Meteor installation.

MongoDB is a NoSQL database. Unlike MySQL or MSSQL or Oracle DBs, here database has collections instead of tables. We have documents in collections insteads of rows in a table. And best of all, all the documents are stored as JSON. You can know more about MongoDB here.

To get the path of MongoDB, make sure you are running the meteor app & then in the terminal, run

ps -ef|grep mongo

And you should see (click on the image to enlarge)

Screen Shot 2014-04-15 at 9.58.02 am

Copy the highlighted part from your terminal and update the command to

/Users/arvindravulavaru/.meteor/tools/c2a0453c51/mongodb/bin/mongo --port 3001

and run it in the terminal. And voila, you will be inside the MongoDB shell (called mongo). If you have never worked with MongoDB before, you can remember the following commands to navigate around and perform basic operation

Command Result
show dbs  will show the list of databases
use <<database name>>  will step you inside the database
show collections  will show the list of collections once you are inside the database
db.collectionName.find()  will show all the documents in that collection
db.collectionName.findOne()  will show the first document
db.collectionName.find().pretty()  will pretty print the JSON data in console
db.collectionName.insert({key : value})  will insert a new record
db.collectionName.update({condition : value}, {$set : {key:value}}, {upsert : true})  will update a record with the given condition & sets the required value. If upsert is true a new document will be created if no documents with matching condition are found
db.collectionName.remove({})  will remove all the documents in that collection
db.collectionName.remove({key : value})  will remove the documents matching the condition

You can learn more about MongoDB here.

Now, lets use the above commands and see our project data. In the mongo shell type

You will see 4 collections. to view what’s inside messages, execute

And the GitHub config can be found here

You can explore further.

Deploying the app to Meteor.com

Meteor provides a free deployment space for your app. You can quickly upload your project so that others can see.

Back to terminal (ctrl + c to come out of mongo shell), run

meteor deploy jojsChatApp

Make sure your appname is unique, else you will end up overriding someone else’s project incase they have not claimed it. 

Meteor will ask for a email address to which this project will be tagged to. Once you provide the email address, your project deployment will start. And also you will receive an email to setup an account.

Then you can navigate to appName.meteor.com to see your app live.

Hope this gave you an idea as to how you can develop lightning fast SPA apps. Now lets look at a complex example.

Events Feed – Multi Page Application

So far, we have seen a simple SPA. Now, lets build a Multi page application using Iron Router & lets use Meteorite to manage packages. Even though we refer to this app as a Multi Page Application, we will still be using only one html file. But Switching views/templates using routes.

Setup Meteorite

Meteorite is a Meteor version manager and package manager. It provides an easy way to run different versions of meteor, use non-core packages, and to install packages from the Atmosphere package repository.

To install meteorite, open terminal/prompt and run

sudo npm install -g meteorite

You can go to Atmosphere package repository and have a quick peek of available packages. You can started of by searching for Bootstrap 3, Routers, SASS etc.

Create Project using mrt

Now, lets use the mrt CLI (Command Line Interface) to create a new project. Back to the root of myMeteorApps, open the terminal and

  mrt create eventsFeed

Your new project will be scaffolded inside the eventsFeed folder. The structure will exactly same as the Meteor setup, except you will see a new JSON file named smart.json. This file will store the list of packages which we have installed.

Application Logic

Our app will have 3 “pages“. One that will list all the events that are presently going on. When a user clicks on an event, we will take him to the event’s chat page. And finally, a page to create a new event.

We are going to use Iron Router to configure/map a page to a template. When the url changes, appropriate template will get triggered.

In the single page application, we have inserted data directly from client side by creating a new instance of the collections. But this time, we will write our database logic on the server side and using Meteor.call() , we will send the data from client and update the database. Implementing a separations of concerns scenario.

We are going to install 6 package for this app

  • 1. Bootstrap 3
  • 2. moment
  • 3. iron-router
  • 4. accounts-ui-bootstrap-3
  • 5. accounts-github
  • 6. accounts-twitter

You can check out more packages here.

Building the App

Back to terminal and cd into eventsFeed folder and run

mrt add bootstrap-3

to add Bootstrap 3. Next run

mrt add moment

to install momentjs. Next run

mrt add iron-router

to install Iron Router. Next run

mrt add accounts-ui-bootstrap-3

to install Accounts UI style with Bootstrap 3 to give a nice look for our login controls. Finally add Twitter and Github account services

mrt add accounts-twitter

mrt add accounts-github

Next, you can run meteor  command at terminal to start the server. Navigate to  http://localhost:3000/ to see the scaffolded app with the basic template.

Now, We refractor our app, make the server and clients folder. Move eventsFeed.csseventsFeed.js and eventsFeed.html into the client folder. Create a new js file named server.js inside the server folder.

And the final project structure should look like

Screen Shot 2014-04-16 at 8.02.42 pm

The updated eventsFeed.html would be

Lines 5 – 28 : This is the code for responsive navbar. You can checkout Bootstrap for other components.

Lines 18 – 22 : If the user is logged in, we will show the Add Event link in the menu

Line 23 : Placeholder for login buttons

Line 30 : Home template. This is our home page template. I have nested template inside template to showcase the reusability of code. Unless is like Else without the If. Here we see if the user is logged in and then hide the banner template. And show a list of available Events using the events template.

Line 76 : Banner template to show the message to login.

Line 105 : Events template will take in the events collection, iterate through each event and will invoke the event template, which will render each event.

Line 38 :  When a user clicks on an event, we will show this eventFeed template. This will show the list of messages for that event. It will only let the logged in users post.

Line 86 : New event Template to show a form, where a user will enter the details and submit

Do notice the prettifyDate handlebar helper. We will get to that in a moment.

Our eventsFeed.css will be

Basic stuff for some look and feel.

Now, on the server, we will create 2 collections and write add events to push the data which these methods receive to MongoDB. The completed server.js would be

Now, the heart of the application, eventsFeed.js. This where we define our routes, write events for posting the data & fetching the data.

As mentioned earlier, we have 3 routes. The first parameter in this.route()  is the route name & will be taken as the template name if no template parameter is supplied. The second argument is the path. On which path, this template/route needs to be invoked. You can find a good tutorial here.

On the Event chat page, when a user lands on the page, we will scroll down to the last post and show the same to the user. On Line 6, we are waiting for the route to be rendered and then firing the scroll event.

On the Add new event view, We will bind a click event to the create button. The pass on those values to the server using the Meteor.call()  Once that is done, we will redirect to the home route.

Our completed eventsFeed.js would be

You can save all the files and back to the  http://localhost:3000/ , you will see

Screen Shot 2014-04-16 at 8.53.24 pm

You know what to do! Go ahead and configure the logins (Or you can use the same from above app, because we are still using the localhost:3000 url).

PS: If you are facing issues while configuring the Twitter and Github services, remove the accounts-ui-bootstrap-3 package and add the default account UI package configure it and then add the accounts-ui-bootstrap-3 package again.

  mrt remove accounts-ui-bootstrap-3

 mrt add accounts-ui  

mrt add accounts-ui-bootstrap-3

Deploy the App

You can deploy the app using

meteor deploy appName

Again pick a unique name.

This completes our post on building apps using Meteorjs.


Thanks for reading! Do comment.
@arvindr21

Tweet about this on TwitterShare on LinkedIn0Share on Google+0Share on Reddit0Buffer this pageFlattr the authorEmail this to someonePrint this page