JavaScript
Article
By Lamin Sanneh

Getting started with Ember and Ember CLI

By Lamin Sanneh

Ember has gone through a lot of changes over the years. One of the biggest ones has been the introduction of the Ember CLI, a command line utility built for Ember. It combines several features including generators, minifiers, CSS preprocessor compilers, autoreload, and ES6 module loaders. This command line tool will help you reduce the time spent on setting up some of your tools such as Grunt and Gulp. We can say that it could be a good alternative to these tools for any of your brand new Ember projects.

In this article, you’ll learn how to build a simple contacts manager application using Ember CLI. This tutorial will be a bit different from the other articles about Ember I’ve published on SitePoint since they did not ship with Ember CLI. However, most of those concepts still apply, so I suggest you to take a look at them and follow on.

The complete code for this article is available on GitHub.

How to Install Ember CLI

To install Ember CLI, you need several dependencies installed first. The first one is Node.js. You need at least the version 0.12.x. Next, the installation of Bower is required, operation which can be done by running the command:

npm install -g bower

Then, to install Ember CLI, run the command:

npm install -g ember-cli

How to Create a new Ember Project

Before we start doing awesome stuff, you need to open a terminal and execute the following commands, in order to create a new project folder with the name contactmanager:

ember new contactmanager

As second step, enter the directory and then install all the npm and the Bower dependencies using the following commands:

cd contactmanager
npm install
bower install

At this point, boot up the built-in Ember server by executing:

ember serve

Your new application can now be accessed at the URL localhost:4200. This is the default port for an Ember application running on your local machine but you can change it if you like. If you followed all the stages indicated, you should now see a header in your browser saying “Welcome to Ember”.

Ember Conventions and Structure

Before diving into building our application, let’s go over some Ember conventions.

The Router and Routes

Routes are the entry points for an Ember application. Routes are defined in the file app/router.js using the Router. They let you have access to different part of your app. For example, if you decide that you need to manage users in your application, you have to define a users route. You can do this using the following syntax:

Router.map(function() {
  this.resource('users', function() {});
});

This will create for us the following URLs:

  • /users/
  • /users/index/
  • /users/loading/

Conventionally, when you define a route, Ember expects to find other associated types such as a route, a controller, and a template. We could decide to create these types explicitly or allow Ember to create them for us. In many applications, you’ll most likely have to create them by yourself, but it’s up to you.

Remember that it’s crucial to differentiate between the Router and a Route. The URL structures we created above are done using the Router. These only show our intention to have those URLs available in our application. We haven’t created the actual routes, but only the URLs for those routes. To create a Route, we’ll have to follow this procedure in the routes’ folder. If you’re confused, don’t worry as I’ll deepen this topic later in this article.

The Controller

Controllers are a type used to store a view state and are located in the app/controllers folder. They work hand in hand with the routes. In this case, the above URL corresponds to /user/ and will need a controller called /users/. Also here, we’re free to choose if defining it by ourselves or not. Controllers also define event handlers for view actions like clicks, hovers and so on.

The Template

The template is the presentational part of Ember. You write it in a templating language called Handlebars which compiles down to plain HTML. Templates go in the app/templates folder.

The Component

Components are little self-contained pieces of functionality. You can think of them as a combination of presentation and functionality which are reusable and are easy to maintain.

Ember-Data

This is a library, maintained by the Ember core team, which complements the Ember core and acts as the front-end ORM for managing data models. There are other alternatives which I haven’t used before and are outside the scope of this article since we’ll be using Ember-data.

The Application

The contact management application we’re going to build will include a list of users with contact information available to them. The application will allow us to create, edit, delete, and view users.

To make our application concise, we’ll be using the fixture adapters which ships with Ember CLI. This acts as a backend except for the fact that no data will be is persisted across page refreshes. To begin, create a new Ember project using ember new contactmanager if you haven’t done it already.

Generate User Model

Move into the project folder and generate a user model using:

ember generate model user

This will create a file called user.js inside app/models with this content:

import DS from 'ember-data';

export default DS.Model.extend({
});

Do the required changes in order to make the export statement look like this:

export default DS.Model.extend({
  firstName: DS.attr(),
  lastName: DS.attr(),
  addressLine: DS.attr(),
  postCode: DS.attr(),
  country: DS.attr()
});

This defines the properties our user model will have.

Generate User Route

Now, add the following lines to your router.js file to make some URLs available to us:

Router.map(function() {
  this.resource('users', function() {
    this.route('show',{path: '/:user_id'});
    this.route('edit',{path: '/:user_id/edit'});
  });
});

We have three new URLs. One of them is to list users, another one to view a single user, and the last one to edit a user’s information. Next, let’s create a users route using:

ember generate route users

This route will be used to retrieve our list of users. Change its content with the following snippet:

import Ember from 'ember';

export default Ember.Route.extend({
  model: function(){
    return this.store.find('user');
  }
});

Setup Fixture Data and Generate a User Template

At this point, let’s add some temporary data to our application. To do that, run the command

ember generate adapter application

This generates a file called application.js in the folder app/adapters/. By default, Ember uses the RestAdapter for querying models. This adapter assumes that you have a back-end system which serves JSON data to your Ember client application. Since we don’t have a backend, in this case we want to use fixture data instead. Therefore, we’ll update the adapter code to be as follows:

import DS from 'ember-data';

export default DS.FixtureAdapter.extend({
});

and add the following to your user model to create some fixtures.

User.reopenClass({
   FIXTURES: [{
      id: 1,
      firstName: 'James',
      lastName: 'Rice',
      addressLine: '66 Belvue Road',
      postCode: 'M235PS',
      country: 'United Kingdom'
   }]
});

If you navigate to the URL localhost:4200/users, you’ll only see the old greeting message and not the user fixture data we have just added. To see the user data, we need to create a template for the users using the command:

ember generate template users

This creates a file called users.hbs in the folder app/templates/. Open this file and updates its content as follows:

<ul>
  {{#each user in model}}
    <li>{{user.firstName}} {{user.lastName}} <span>Edit</span></li>
  {{/each}}
</ul>
{{outlet}}

You should now see a list of users appear with an edit text next to each one. Because we only have one user in the fixture data, we’ll see just one user. Feel free to add as more user objects to the user fixtures as you prefer. Just make sure that each one has a unique ID.

Display a Single User

Now that we’ve listed our users, let’s see a way for displaying a user’s full information. First of all. change the code in users template by changing the li element to be as reported below:

<li>
   {{#link-to 'users.show' user}} {{user.firstName}} {{user.lastName}} {{/link-to}}
   <span>Edit</span>
</li>

This should surround each users name with a link. When you click the link, only the URL is supposed to change whilst everything on the page stays the same. This is because we haven’t generated a single user template.

Run the command:

ember generate template users/show

At the moment, the created template (app/templates/users/show.hbs) is empty. Open it and add the following code:

<p>{{#link-to 'users' }}back{{/link-to}} to Users</p>
<p>First Name: {{model.firstName}}</p>
<p>Last Name: {{model.lastName}}</p>
<p>Address: {{model.addressLine}}</p>
<p>Postcode: {{model.postCode}}</p>
<p>Country: {{model.country}}</p>

Doing so, you should be able to see the full information for each user you click on.

Edit a Single User

If you want to edit a single user, there are few simple steps you have to follow. To begin, first link to the user edit route by wrapping the Edit text next to each user’s name with a link. Then, change Edit to

{{#link-to 'users.edit' user }}Edit {{/link-to}}

Next, let’s generate a user controller using:

ember generate controller users/edit

Inside (the user controller) change the content to be as listed below:

import Ember from 'ember';

export default Ember.Controller.extend({
  actions: {
    saveUser: function(user){
      user.save();
      this.transitionToRoute('users');
    }
  }
});

Once done, generate a template for editing users using:

ember generate template users/edit

In the new template app/templates/users/edit, paste the following code:

<p>{{#link-to 'users' }}back{{/link-to}} to Users</p>
<form {{action 'saveUser' model on='submit' }} >
  <p>First Name: {{input value=model.firstName}}</p>
  <p>Last Name: {{input value=model.lastName}}</p>
  <p>Address: {{input value=model.addressLine}}</p>
  <p>Postcode: {{input value=model.postCode}}</p>
  <p>Country: {{input value=model.country}}</p>
  <p><input type="submit" value="Save" ></p>
</form>

This code calls the saveUser() function on our controller when we submit the form. The function is passed the user being edited and saves the modified information.

With this change in place, when you click on the edit link for a user, you can edit his details. You can get them saved when you click the save button, upon which you are redirected back to the users’ list. Hurray! We now have a simple contact list manager.

You can turn this into a full application by hooking it to a real backend to persist data across page refreshes. I also encourage you to add a delete functionality to the application so you can delete users who are not needed whenever you want.

Conclusions

Ember is a framework for building ambitious web applications. It has a philosophy of convention over configuration, this means that it is based on several common decisions and has many default (conventions) which make the development process easier for you. In this way, you don’t have to make a lot of trivial decisions during development.

I hope you enjoyed reading this tutorial and learned something new about how to use such a powerful but simple JavaScript framework in your projects. Please let us know your thoughts in the comments below. You can find the code for the application on GitHub.

  • Mike North

    You don’t need “this.resource” in your router anymore, with the latest release of ember — you can just nest “this.route”

  • Tmock12

    You should also use the new ‘each as’ syntax. so `{{#each user in model}}` becomes `{{#each model as |user|}}`

  • greg5green

    My favorite part of this article is how it doesn’t mention actually adding any fixtures so if you haven’t worked with Ember before, you’d be completely lost.

  • hangaroundtheweb

    Typo in line
    ember generate users/edit
    should be
    ember generate template users/edit

    • Aurelio De Rosa

      Error fixed, thank you.

  • Thanks for this article! You showed in a very easy way how to create an useful app with Ember (that is NOT a simple fw ;D).

    Suggestion: For the next articles, do not jump crucial steps like the fixture data. Without that information, that also isn’t trivial, the reader won’t be able to connect the dots.

  • Thank you everyone who has interest in the article. For the readers below, the article has now been updated to show how to add fixture data. Just make sure you set the export to a User variable.

  • shubahngi

    Error while processing route: users.index User is not defined ReferenceError: User is not defined

    on http://localhost:4200/users

  • Don

    On the “display a single user” step I got a “More context objects were passed than there are dynamic segments for the route” error. To add a dynamic segment add a : before the dynamic part of the route. So in router.js modify the line to look like the following this.route(‘show’, {path: ‘/:user_id’}); I hope this help the next express adventurer.

Recommended
Sponsors
Get the latest in JavaScript, once a week, for free.