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.