Getting Started with Meteor

Jul 16 2014 by David Turnbull | 5 Comments

Meteor is a full-stack development platform that makes it easier than ever before to build real-time web applications. This tutorial will get you up and running with Meteor in no time.

What is Meteor?

Meteor will enable you to build web applications much faster — even ambitious ones that seem like they were developed by big teams with big budgets — using nothing but JavaScript, CSS and HTML. And, what’s more, with Meteor, you’ll simply have more fun because it’s optimized for developer-happiness.

Originally known as "Skybreak" back in 2011, Meteor has since raised $11.2 million in venture capital, grown an active and dedicated community and has become "the hot new thing" in the world of web development.

Meteor did all that even before reaching its version 1.0 release (currently, it’s at 0.8.2, but the releases are coming big and quick).

There’s a lot to love about this web development platform, here are a few of them:

  • You don’t have to be a seasoned developer to make a start. If you’ve never made a web application before, Meteor is one of the easiest introductions to the craft, while still being incredibly powerful enough to be the only platform you’ll ever want to use.
  • Your web applications are real-time by default. In the majority of cases, you don’t even have to think about making your applications real-time. You work as you normally would, and the real-time features just happen. This means less code and shorter development cycles.
  • The community is extremely helpful. You won’t be left alone if you embark on your journey into Meteor. There’s blogs and books and screencasts and all the other sort of help you could possibly want.
  • Meteor is open source. A GitHub repo is available if you want to dive into its inner workings (or even contribute to its development).

If you’re not quite sold on the Meteor JavaScript framework yet, check out the official Meteor site and this popular tutorial screencast from the creators of Meteor.

Screenshot of Meteor front page.

A Meteor Tutorial for Beginners

In this tutorial, I’ll share an introduction to Meteor that anyone with a basic understanding of JavaScript can follow. If you know what "variables" and "functions" are, you’re good to go. If not, read this free online book first.

Especially if you’re a web designer looking to add "and developer" to your job title, this tutorial should act as a fun little nudge in the right direction.

In this tutorial, we’ll build a very rudimentary blogging app together. Doing this will allow us to explore the most powerful features of Meteor by way of a functional web app example.

Preview of the results of this Meteor tutorial.

View Demo

Let’s get started.

Step 1: Install Meteor

Note: The following installation instructions are for Mac OS X and Linux. If you’re on Windows, visit win.meteor.com to learn how to install Meteor. If you’re already familiar with command line interfaces (CLI), the following are just basic commands that you probably already know regardless of the operating system you currently use.

To begin, open the command line. On Mac OS X, this is the Terminal application. If you’re on Linux, the name of the command line interface can vary, but since you’re using Linux, I’ll assume you know what it is.

Issue this command:

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

The command above will start the installation process. It’ll only take a few seconds and, just like that, Meteor is installed and ready to use.

Step 2: Create a Project

For every web application we develop, we’ll need to create a project.

But before we create a project, to keep things nice and tidy, let’s create a folder that will store all of our Meteor web applications.

Use the following command to create a directory named "Meteor" in your computer that will store all of your Meteor projects:

mkdir Meteor

Let’s navigate into the "Meteor" directory with the change directory command:

cd Meteor

Now we’ll create our first Meteor project. We’ll name our first project HelloWorld. Just use the following command:

meteor create HelloWorld

The command above will create a "HelloWorld" folder that contains three base files:

  1. HelloWorld.html
  2. HelloWorld.js
  3. HelloWorld.css

A Meteor app can grow beyond these first three files, but they’ll be enough for this tutorial.

Step 3: Launch Your Local Server

By default, our project contains some code for a demo application.

To see this demo application, move into our project’s directory:

cd HelloWorld

Once you’re in the HelloWorld project directory, launch the local server by issuing the following command:

meteor run

That command will now let us see our app through a browser simply by navigating it to the following URL:


http://localhost:3000

You can use whatever browser you prefer, though I recommend Google Chrome because of the browser’s built-in developer and debugging tools, such as its JavaScript console which we’ll be using in this tutorial.

The default app template should resemble the following:

If you click the button that says "Click" it doesn’t seem to do anything. But something is happening though.

Chrome’s JavaScript console

Whenever you click on the "Click" button something is happening. To see it, in Google Chrome, go ahead and do the following:

  1. Click on the Menu icon (located at the top-right of the window)
  2. Hover over to the Tools option
  3. Select the JavaScript console option

Alternatively, you can press Option+Command+J (Windows: Ctrl+Shift+J) to open up the JavaScript console.

The JavaScript console is the client-side equivalent of the command line. This will be a powerful tool as you’re developing your Meteor apps.

The command line runs on the server (where the application is hosted) while the JavaScript console runs on the client (in the user’s browser).

With the JavaScript console open, press on the "Click" button again. You’ll see a message appear in the console with each press of the button:

JavaScript console showing a click event recorded by Meteor.

That’s the extent of what’s happening, you pressed the button, so it’s not so exciting.

We’ll be using the console again in this tutorial, so please leave it open.

Step 4: Create a Collection

Usually, this is where most tutorials would show how to create a user interface with Meteor, but I think it’s easier to start by talking about the database. It’s not as sexy of a subject compared to the UI, but it’s a more pragmatic one.

Meteor uses MongoDB by default, but there will be more RDMS options coming in the future.

MongoDB in itself is a huge topic, but it’s one of the easier databases to use as a beginner because there’s a lot of things you don’t have to think about (for example, it’s good at avoiding injection attacks by itself, unlike SQL).

We’re now going to use the database by creating a collection.

A collection is equivalent to an SQL table. For example, if we were making a WordPress clone, we’d create a collection for posts, a collection for pages, a collection for comments, a collection for users, and so forth. There’d be a collection for each type of data.

Let’s create our first collection: Open the HelloWorld.js file in your favorite code editor, delete everything in it and replace it with:

new Meteor.Collection('posts');

In this tutorial, we’ll pretend that we’re creating a blogging platform, so here, we’re making a collection named "posts" that will store data such as post titles, post contents and post statuses (i.e. whether the post is published or still a draft).

We do, however, need a convenient way of referencing the collection we just created, so we’ll amend our code by slapping an object name in front it. How about we call this collection, "BlogPosts"? Update the code block above so it now looks like this:

BlogPosts = new Meteor.Collection('posts');

Note: We’re intentionally not using the var keyword since we want this to be a global variable that we can access through all of our files.

Save our HelloWorld.js file, switch to your browser, and enter the name of the following code block into the JavaScript Console.

BlogPosts

You should receive a response that confirms the collection exists, which is all we need for the time being.

Step 5: Manipulate Your Collection’s Data

Inside the JavaScript Console, enter the following:

BlogPosts.insert({
  title: 'Hello World',
  content: 'Content goes here.',
  published: true
});

Note: Newlines and extra spaces in the JavaScript console are ignored, so the above can be written in one line. The formatting above is for readability.

¬†We just used the insert function to create a document inside our collection. A document is equivalent to a row in a SQL table. We’ll create a new document for each blog post in our web app.

It’s worth pointing out that:

  • We don’t have to design the structure of our collections. The structure is created on the fly. When we need a new field, we just define it.
  • We can mix and match data types. We have strings in the first two fields (title and content, but the third field (published) is a boolean field (i.e. it can only hold the value of either true or false).

So that we have data to work with in the next few steps of this tutorial, insert a few more documents (like 5 or so) into the BlogPosts collection via the JavaScript console using the same code block as above.Try to use different values for the title and content fields, and alternate between true and false for the published field.

Step 6: Retrieve the Data

In a moment, we’ll create a template that shows a list of blog posts.

Before we do that though, we need to create a JavaScript function that retrieves the blog posts from our collection.

In the HelloWorld.js file, add this code block below the previous one:

Template.listBlogPosts.post = function(){
  // code goes here
}

The code above might look weird and abstract to you, so let’s break it down:

The Template portion searches through all the templates in our project. We haven’t created a template yet, but we’ll get to that in a moment.

The listBlogPosts part is the name we’ll assign to our soon-to-be template. We can name our templates whatever we want.

The last part, post, is an arbitrary name for our function that we’ll soon reference.

Within the function block we created above, we write the code that will retrieve all the blog posts, like so:

Template.listBlogPosts.post = function(){
  return BlogPosts.find();
}

So now we have this function called post() and, within the post() function, we return the entirety of our BlogPosts collection.

We only want this code running on the client. Do do this, let’s wrap our code in an isClient conditional statement:

if(Meteor.isClient){
  Template.listBlogPosts.post = function(){
    return BlogPosts.find();
  }
}

All code inside this conditional will only run in the user’s browser (and the rest of the code in this tutorial will be placed inside this conditional).

That’s all the database talk for the moment.

Let’s start delving into the so-called "magic" of Meteor: Templating.

Step 7: Create a Template

To move onto the design part of this tutorial, open the HelloWorld.html file, delete all of its content and replace it the following:

<head>
  <title>My Blog</title>
</head>
<body>
  <!-- code goes here -->
</body>

Notice that we didn’t use <html> tags, nor have we manually included any CSS or JavaScript files. This is because Meteor will do all this for us.

Beneath the code block above, let’s create our first template:

<template name="listBlogPosts">

</template>

If you save the file and switch back to the browser at this point, the template won’t appear. Why? Because we have to reference it, giving us complete control over where and when the template appears.

Between the <body> tags, write:

{{> listBlogPosts}}

When we use double-curly braces ({{ and }}), we’re using the Spacebars templating syntax that comes packaged with Meteor. Spacebars allows us to make our templates dynamic. The greater than symbol (>) is specifically used when referencing a template.

Step 8: Displaying Data

Inside our listBlogPosts template, add the following block of code:

<template name="listBlogPosts">
  {{#each post}}
    {{title}}
  {{/each}}
</template>

Here, we’re looping through the data returned by the post function we created earlier. It lets us display a list of blog posts from our BlogPosts collection and the fields associated with each document. (In the code above, we’re showing the "title" field.)

To make our template look a little nicer, update our code above so it now looks like this:

<template name="listBlogPosts">
<div id="content">
  {{#each post}}
    <div class="post">
      <h2>{{title}}</h2>
      <div class="entry">
        {{content}}
      </div>
    </div>
  {{/each}}
</div>
</template>

Now we can open the HelloWorld.css stylesheet, write whatever styles rules we like, and they’ll all be applied to our template’s HTML elements.

Step 9: Retrieving Specific Data

At the moment, our app will display all of the blog posts from our collection, rather than just the posts that have the published parameter set to true.

To fix this, update the post() function from this:

Template.listBlogPosts.post = function(){
  return BlogPosts.find();
}

…to this:

Template.listBlogPosts.post = function(){
  return BlogPosts.find({ published: true });
}

In the above code, we’ve passed the published parameter into the find function, allowing us to retrieve only the published posts, i.e., all documents that have published: true.

Step 10: Create a Form

While we’re never going to build a complete blogging application in a single tutorial, we could at least build an Add New Post web form that will act as the interface for adding new content into our rudimentary blogging engine. Earlier, in Step 5, we added new documents in our collection through the JavaScript console, and now we’ll create an interface for this process.

First, create a new template in our HelloWorld.html file:

<template name="addPostForm">
<form>
  Title: <input type="text" id="titleField"><br />
  Content: <textarea id="contentField"></textarea><br />
  Publish? <input type="checkbox" id="publishedField"><br />
  <input type="submit">
</form>
</template>

There’s nothing remarkable about this form template. The only detail worth noting is that each field has a unique id attribute that we’ll soon reference.

Also, don’t forget to reference the following somewhere between the <body> tags so the user can see our form (just like with our listBlogPosts template in Step 8):

{{> addPostForm}}

To make this form do something, switch to our JavaScript file and, inside the isClient conditional, write the following:

Template.addPostForm.events({
  // code will go here
});

Here, we’re using the events function to attach an event listener to our addPostForm template.

Events are things like clicks, double-clicks, scrolling, mouseovers and form submissions. They’re things that occur when a user is navigating our web application, and we can write code that reacts to them.

In this example, we’ll create an event listener that is triggered when our form is submitted:

Template.addPostForm.events({
  'submit form': function(){
    console.log("Form submitted");
  }
});

This is what’s happening with the above:

  1. First, we use the submit keyword to define the event type to watch out for. There’s a range of event types available, all of which can be found in Meteor’s official docs.
  2. Second, the form keyword references all the form elements within our template, so this is where we’re simply attaching our event listener to the one and only <form> element in our web app.
  3. Third, we associate a function with our form submission event, and it’s within this function that we write the code we want to execute when the ‘submit form’ event happens. In this case, a simple message that reads "Form submitted" will appear in the JavaScript console when the form is submitted.

There’s a problem though, since whenever we submit the form, there’s a slight flicker. This is because forms have a default behavior that we need to disable so it no longer interferes with our code.

To disable the form’s default behavior, update the code block above so it now looks this:

Template.addPostForm.events({
  'submit form': function(event){
    event.preventDefault();
  }
});

Note: After updating the code block and removing the console.log() invocation, you’ll no longer see the "Form submitted" message in your console.

We’ve done two things:

  1. We’ve created a function argument named event that we can reference withing the 'submit form' function as the current instance of the event while it’s occurring.
  2. We used the preventDefault() function on the current event, which stops our form from behaving how it would usually behave.

With that housekeeping out of the way, let’s make our form do something useful.

Step 11: Getting Data from Inputs

The end goal is to have the data from our form inserted into the BlogPosts collection that we created earlier. To move us towards this goal, let’s grab the data from our form fields. This is a two-step process.

First, we pass another function argument into our 'submit form' function, which we will name template:

Template.addPostForm.events({
  'submit form': function(event, template){
    event.preventDefault();
  }
});

We’ve added the template argument to allows us to search through the template that our event is attached to. In this case, we can search through the addPostForm template from within our event.

The second step of our process is to perform three searches. We can do this like so:

Template.addPostForm.events({
  'submit form': function(event, template){
    event.preventDefault();
    var titleVar = template.find('#titleField').value;
    var contentVar = template.find('#contentField').value;
    var publishedVar = template.find('#publishedField').checked;
  }
});

The above invokes the find function that will search through our templates using their HTML IDs, i.e. #titleField, #contentField, #publishedField, as the references for the relevant input fields, and then pulling the values from them. We then store these values in some variables: titleVar, contentVar and publishedVar.

Note: For the third variable, publishedVar, the value will either be true or false based on whether or not the "Published?" checkbox is checked.

Below these statements, we use the insert function to move the data from our form and into the BlogPosts collection:

BlogPosts.insert({
  title: titleVar,
  content: contentVar,
  published: publishedVar
});

At this point, the code should resemble this:

Template.addPostForm.events({
  'submit form': function(event, template){
    event.preventDefault();
    var titleVar = template.find('#titleField').value;
    var contentVar = template.find('#contentField').value;
    var publishedVar = template.find('#publishedField').checked;
    BlogPosts.insert({
      title: titleVar,
      content: contentVar,
      published: publishedVar
    });
  }
});

Now, the form should work as expected. When you submit data through it, it will automatically appear in our app’s interface as long as the "published" option is checked.

Conclusion

We’ve only scratched the surface of Meteor, but we’ve also covered the most essential core concepts that you’ll continue to use during your career as a Meteor developer.

Our final blogging application might not be particularly grand, but:

  • We wrote very little code in a very short amount of time
  • The application functions in real-time without us doing anything special

I hope you’re now at least a little bit curious enough to explore Meteor a little further. It’s an increasingly popular web app platform that has many great years ahead of it.

Related Content

About the Author

David Turnbull is the founder of Meteor Tips, a site that publishes tutorials about the Meteor JavaScript framework, and author of Your First Meteor Application. David’s been working on the Web since he was 12 years old. Follow him on Twitter @meteortips.

5 Comments

webdevolution

July 16th, 2014

that is really nice, how about deploying node.js and mongo to a live server and not just working on localhost environment? the app has to run somewhere in order to be accessible via the web. where do you get hosting that supports these requirements apart from virtual servers that you configure by yourself.

Humayun Hashmi

July 17th, 2014

Looks nice, but it is a bit costly…. I think they will have to drop the price…. just a little bit :)

Pip

July 18th, 2014

your last JS code has errata, change it to:

BlogPosts = new Meteor.Collection(‘posts’);

if(Meteor.isClient) {
Template.listBlogPosts.post = function(){
return BlogPosts.find({ published: true });
};

Template.addPostForm.events({
‘submit form’: function(event, template) {
event.preventDefault();
var titleVar = template.find(‘#titleField’).value;
var contentVar = template.find(‘#contentField’).value;
var publishedVar = template.find(‘#publishedField’).checked;
BlogPosts.insert({
title: titleVar,
content: contentVar,
published: publishedVar
});
}
});
}

note: you also don’t have to type ‘meteor run’ to run meteor. Just type ‘meteor’

I like your tutorial. Straight and to the point. Thanks!

Jacob Gube

July 25th, 2014

@Pip: Thank you for bringing the issue to our attention — we really appreciate it. We’ve corrected the last code block.

Pip

August 2nd, 2014

Also in your instructions you say the command
$ meteor run

you just need
$ meteor

and the server will run

Leave a Comment

Subscribe to the comments on this article.