Rapidly Prototyping Web Applications With Meteor JS

- Bharani M

What is Meteor JS?


Meteor is a Javascript framework that makes it very easy to create web applications. Meteor abstracts away the menial and configuration-related details leaving us with a just the set of tools that is needed to create a web application.


"Meteor is a platform for building top-quality web applications in a fraction of the time". 

 What is Meteor JS?

  • Meteor is built on top of Node JS.
  • It sits between your app's database and the user interface and makes sure that both are kept in sync.
  • You use a single language (Javascript)  on the server and the client. Meteor lets you share code between the two environments.
  • Works best when creating multi-user/realtime apps

If you are familiar with the command line, you’ll know that this command just downloads some files from meteor.com and pipes it to the bin/sh directory.

bin/sh is the location of the script interpreter "Shell", which will run the script. 

Installing Meteor

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


Creating A Meteor App

meteor  


meteor create contacts
cd contacts 


This meteor command takes care of loading up all our files and scripts.

Now open up a web browser and navigate to http://localhost:3000/.
 

Meteor Internals 


Meteor is divided into two components - 

Packages 

Modules (chunks of pre-written code) that you can use to build your application(webapp, templating, emails etc)

Command Line Tool (meteor)

This is similar to rake (ruby) or jake (nodejs)

meteor create my_app
meteor reset


Packages

Packages are modules (or chunks) of pre-written code that you can use in your applications. There are 5 types of packages -
 
  1. Core Packages - These packages are used in almost every meteor app.
  2. Smart Packages - Optional Packages that come bundled with Meteor and you can use for performing specific actions (emails, coffeescript etc)
  3. Atmosphere Packages - 3rd party (community-written packages that can be install via meteorite.
  4. NPM modules - Does not work out of the box but can be used.
  5. Local packages - Files that you put into /packages folder inside your Meteor app.

Using Meteor Smart Packages

Small JavaScript programs that can inject code into the client or the server. 
Similar to jQuery plugins, RubyGems or NPM modules. Can be used to add functionality to app (send emails, add user accounts) or extend the build process ( precompile coffeescript or less files).

meteor list
meteor list --using
meteor add  package_name
meteor remove package_name 

Command Line Tool

Meteor's Command line tool is similar to rake (ruby) or jake (nodejs). This does all the background work of collecting, reading, compiling (pre-processing coffee/scss/less files) and minifying. 

The command line tool also lets you perform app specific actions like interacting with your database, deploying/bundling you app, viewing logs, adding/removing packages etc.

Principles


  1. Data on the wire
  2. Single Language
  3. Database Everywhere
  4. Latency Compensation
  5. Full Stack Reactivity
  6. Embrace the ecosystem
  7. Simplicity Equals Productivity



1. Data On The Wire

After the initial page load, only data is sent between the server and the client. Assets like CSS/JS files are not reloaded. 
Makes your application faster and more responsive
 

2. Single Language

Javascript everywhereMeteor uses a Nodejs wrapper on the server. On the client, apart from HTML/CSS, only javascript is used
 

3. Database Everywhere

Meteor gives your complete database access on the client and the server. Meteor mirrors the actual database on the client using minimongo. Local (Browser) cache is kept in sync with the actual database at all times. 


This is just the default setting (due to the autopublish and insecure package being enabled) - works great while starting off on a new project. Client database access can be restricted very easily.

 

4. Latency Compensation

Way to simulate immediate database access.

As soon as you make any changes to your database (adding a record, editing a record) - the changes are reflected on the UI immediately without waiting for a response from the server.
 After the server finishes processing the request, the UI is synced again.

5. Full Stack Reactivity

Everything in Meteor is event-driven. The server code, UI and database updates all happens as a result of user's actions (like clicking a button, submitting a form etc)

6. Embrace The Ecosystem

Meteor is open source. It is built on top of a lot of open source projects like Node/MongoDB. When these projects are updated, Meteor improves with them.
 

7. Simplicity = Productivity

Meteor provides a clean and simple API to help you build apps easily. It is consistent and very well documented.

Hot Code Reload

One of the really cool things about Meteor is the concept of "Hot Code Reload". What essentially means is that, any changes made to the HTML, CSS and Javascript files will be automatically picked up by Meteor.  

So once you save a file after making changes, the browser will automatically reload to display the changes. You don't have to restart the application or even refresh your browser. 

Load Order

Meteor has a set of rules that dictate the order in which files are executed. Instead of using dependency management, you should organize your files according to these rules

  1. Files in the lib directory are loaded first
  2. Files that match   main.*  are loaded last
  3. Files in subdirectories are loaded before files in parent directories (deepest to shallowest)
  4. Within a directory, files are loaded in alphabetical order.

Files in the root directory are loaded both on the client and the server.
Files inside /client  directory only run on client and those inside /server  directory only run on the server

Separating Client/Server Code

if( Meteor.isClient) {   console.log("client");}
if( Meteor.isServer ) { console.log("server");}
Meteor lets us create two folders - server   and  client  . The code that is inside of the server directory will only be executed on the server and similarly, the code that is inside the client directory will only be executed inside the browser
Meteor provides us with isClient and isServer checks to separate out what part of the code needs to be executed on the server and what needs to be executed inside the browser.


HTML and Templates

HTML files in a Meteor app are different from regular HTML files. There is no <!doctype>, no <script> tags and no css imports.

There are three root level tags - 


<head></head>

<body></body>

<template></template>



You can create multiple html files in an app. If there are multiple html files, all the <head> tags are concatenated and all <body> tags are concatenated.

Templates

Templates are regular HTML expressions, but with the ability to embed expressions (variables, values of properties etc).

Without Handlebars
<div>{{ name }} is {{ age }} years old.</div>
$("div").text(name + "is " + age + " years old.");
With Handlebars

Creating A Template

<template name="hello">  <h1>Hello, world</h1></template>  
<template> is a root level tag that Meteor provides us to create templates. Template names should be unique.

<body>
{{> hello }}</body>

There are three expressions that can be used inside Meteor's templates - 

Partials

Partials use the {{> template_name}} syntax. Meteor simply replaces the partial with the template of the same name (in our case postItem).

Expressions

Expressions use the {{ title }} syntax. Meteor replaces this with the value of a property of the current object, or the return value of a template helper.

Block Helpers

Block Helpers are conditional statements to control the flow of template. Examples - {{#each}} ... {{/each}}    {{#if}} ... {{/if}}

Handlebars Block Helpers

Inside the each block, the value of 'this' is set to the currently iterated object. There is no need to call this.fullName.
{{#if currentUser }}    <p>Secret View</p>{{else}}    <p>Access Denied</p>{{/if}} 
{{#each contacts}}    <p>Name: {{fullName}}</p>{{/each}}    
{{#unless newUser}}     <p>Welcome back</p>{{else}}    <p>Good to have you here</p>{{/unless}}


Template Helper Functions


To interact with templates with javascript, Meteor converts all template sections into JavaScript functions that are accessible via a global Template namespace.

To provide data to templates, add functions on Template.template_name object.

Template.hello.name = function() {  return "Bharani" + "M";}

Template.hello.name = "Bharani";
In Javascript file

In HTML file

<template name="hello"> <h1>Hello, {{ name }}</h1></template>


Template Events

To respond to user inputs, we need to listen for events like “click”, “double click”, keypress” etc.   The event and the target element is specified as a string value by a space. This forms the key of the object. The callback function that gets executed when this event occurs is defined as the value.  

Template.hello.events({
    “click input” : function(e, t) {
        alert(“You clicked the input.”);
    }
}); 

Template Events

Reactivity

Reactive programming 
Results will be automatically recalculated whenever data associated with that piece of code changes.

Reactive data sources - a data store that will update its templates when its value itself changes

  • Session Storage
  • Collections
  • Meteor.user

Reactive contexts - run code as a reactive computation 

  • Templates
  • Deps.autorun

Session Storage


Global reactive store of data
one session - accessible everywhere on the client

Session storage allows us to store key-value pairs that are reactive in nature. This can be used to keep track of the current page or current user or for keeping our UI in sync.

Session.set("currentTask", "Learn Meteor");
Session.set("currentPage", "documentationPage");
Session.get("currentTask"); 
Session.get("currentPage"); 
Session.equals("currentTask", "Learn Meteor");

Collections + MongoDB

Persistent Data Storage


The client and server share the same database API. Meteor automatically synchronizes data between client and server


Every Meteor client includes an in-memory database cache. Server publishes sets of JSON documents and clients subscribes to those sets.

Meteor currently only supports MongoDB for persistent data storage

Collections

Contacts = new Meteor.Collection("contacts");
Collections are a way to talk to the Mongo database. 

Collections allow us to publish and subscribe to certain sets of data and take care of  synchronizing real-time data to and from each connected user's browser and the Mongo database .

Collections mimic Mongo's API closely.

Server Side Collections

On the server, Collections act as the interface for talking to Mongo database. Server side collections allow us to use Mongo commands - 
Contacts.insert()
Contacts.update()
Contacts.find()
Contacts.remove() 

Client Side Collections


On the client, Collections act as an in-browser cache of the actual Mongo database. It contains a subset of the actual data and provides immediate access to data.

No round-trip to server to get the data as it is pre-loaded on initial page load.

Minimongo

Working With Collections

   Inserting Records

Contacts.insert({ name: "Bharani" }); 
   Finding Records
Contacts.find();
Contacts.find({ name: "Bharani" });
Contacts.findOne({ name: "Bharani" }); 
   Updating Records
Contacts.update({ name: "Bharani" }, { $set: { name: "John Doe" }}); 
   Deleting Records
Contacts.remove({ name: "Bharani" });  

MongoDB Crash Course


Document oriented database

Alternative to Relational Database (RDBMS) Systems


Mongo database can have multiple collections. Collections are similar to Tables.
Collections can have multiple documents. Documents can be thought of as 'rows'
Documents can have multiple fields. Fields are similar to columns.

Each document inside a collection can have unique set of fields. It is schema-less.

When we get data from Mongo, we get a cursor - actual execution only happens when necessary.

MongoDB Crash Course

Every document must have unique _id field. This field is indexed by default.

db.collection_name.find({ field1: value1, field2: value2 }); db.collection_name.find({ field1: { $gt: 100 }}); db.collection_name.find({ field1: { $lt: 100 }}); db.collection_name.find({ field1: { $exists: false }}); db.collection_name.find({ field1: value1, $or: [{field2: value2}] }); db.collection_name.find().sort({ name: 1 });  db.collection_name.find().count();db.collection_name.count({ age: { $gt: 18 }});db.collection_name.find({}, { age: 1, _id: 0 });

MongoDB Crash Course


db.collection_name.update({ title: "Post #1"}, { $set: { votes: 0 } })

db.collection_name.update({ title: "Post #1"}, { $inc: { votes: 1 } })
db.collection_name.update({ title: "Post #1"}, { $push: { tags: "first_post" } })
db.collection_name.remove( { type : "food" } )

db.collection_name.remove( { type : "food" }, 1 )

MapReduce, Geospatial, Denormalization, Two Phase Commits

Application Structure





You can write an entire app in just one file.
Meteor provides you an efficient way to structure and organize your files. There are no script tags, no loader libraries and no dependency management. 
Just put files in appropriate folders and Meteor will pick it up automatically.

Application Structure


  • /client  - For code that only runs on the client. Meteor pre-processes files in this folder and minifies it before rendering. Place for putting CSS/SCSS/Less files.
  • /server  - For code that only runs on the server. Keep your API keys  and other private data files in this folder so that it is not accessible by users. (You can also use /private  for this)
  • /public  - Place to store images, robots.txt etc. (CSS files are not considered static assets)

Application Structure


Accounts

Meteor provides a pre-built user authentication module. It includes support for 3rd party authentication services (oauth)

accounts-base, accounts-password, accounts-facebook, accounts-github, accounts-google, accounts-meetup, accounts-twitter, or accounts-weibo 

Also include a UI that provides login/signup forms

accounts-ui 

Accounts

meteor add accounts-base accounts-password accounts-ui 

<template name="header">
    {{loginButtons}}
</template>

{{#if currentUser }}
   <h1>Logged in</h1>
{{/if}} 

Meteor.user()
Meteor.userId() 

Security



Restricting Read Access

Publications and Subscriptions



Restricting Write Access

Allow/Deny
Meteor Methods

Restricting Read Access - 

Publish/Subscribe

Meteor includes autopublish package by default which automatically mirrors all data from the server on the client.

meteor remove autopublish 

Client should only get a subset of data. To restrict data access, we create a publication channel. Publication is a way to transfer data from server to client.
Then client then connects (subscribes) to that channel.

Publications control what data should be passed from server.

Publish/Subscribe

From server
From Client
Meteor.autosubscribe(function() {
    Meteor.subscribe("contacts", Meteor.userId());
}) 

Meteor.publish("contacts", function() {
    return Contacts.find({ userId: this.userId });
})

Restricting Write Access -

Allow/Deny


Permission system that applies to all database changes initiated from the client. Declarative way to specify what database modifications are allowed
Contacts.allow({
	insert: function(userId, doc) {
		return !!userId
	},

	update: function(userId, doc) {
		if(userId && doc.userId == userId) return true;
		return false;
	},
	
	remove: function(userId, doc) {
		if(userId && doc.userId == userId) return true;
		return false;
	}
});

Restricting Write Access - 

Meteor Methods

Meteor.call("addOne", {name: "bharani"}); 

Methods are functions that are called from the client but are executed on the server.
From Server
From Client

Meteor.methods({
    addOne: function(obj) {
      Items.insert(obj);
    }
}) 

Deploying


meter deploy contacts-app-demo.meteor.com 

meteor bundle contacts.tgz
tar -zxvf bundle.tgz 

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 . 
npm install -g meteorite  mrt create my_appmrt add ... (add a package from Atmosphere repository)



Useful Meteorite Packages

  • Router
  • User Roles
  • Admin UI
  • Pagination
  • Animate
  • SCSS
  • Bootstrap 3 / Zurb Foundation
  • Regulate/jQuery Form Validations
  • Momentjs

Learning Resources

Documentation

Meteor Youtube Channel

Code examples

Video Tutorials

 

Thanks

Rapidly Prototyping Web Applications With Meteor JS

By bharani91

Rapidly Prototyping Web Applications With Meteor JS

  • 2,696