cult3

Working with Routes in Ember

Apr 27, 2015

Table of contents:

  1. Ember’s assumed defaults
  2. Ember CLI generators
  3. Creating a new Route Model
  4. Loading Model data
  5. Choosing the Controller and the Template
  6. Transitioning and Redirecting
  7. Conclusion

Last week we looked at the basics of routing in Ember. Routing URLs is one of the core components of a framework because it is the URL that drives the behaviour of the application.

I mentioned last week that you don’t always have to specify things in Ember because certain defaults will be assumed.

This is convention over configuration, a trait of rapid application development that will make your life a lot easier.

To enable this to work, Ember implements some magic behind the scenes.

Today we are going to look at understanding this magic, as well as working with Route objects.

Ember’s assumed defaults

Last week we looked at some of the conventions of Ember when defining routes.

For example, when you define a new named route of posts, Ember will assume you will be be using:

  • a URL of /posts
  • a Controller called PostsController
  • a Route called PostsRoute
  • a template called posts

Last week when we were creating a new route, you might have noticed that everything seemed to work, despite the fact we did not create the PostsController, PostsRoute or posts template.

If Ember does not find these files, it will generate them for you at run-time.

This means things will automatically work out of the box, but if you want to customise the behaviour of any of these objects, you can simply create your own object that will be used instead.

Ember CLI generators

One of the really good things about using Ember CLI is that it comes with generators to create a lot of the boilerplate code and files you will need.

Open terminal and run the following command:

ember help generate

You should be presented with a list of all the generators you have available. You can even define your own blueprints that will be used instead of the default blueprints if you want to do something a slightly different way.

Creating a new Route Model

In order for an application to be useful, we’re going to need some data to work with.

One of the responsibilities of the Route is to define the model.

So the first thing we can do is to generate a new resource:

ember g resource posts

This will generate a new resource named posts.

This will create a couple of new files in your project, but we won’t worry about those for now. The only file we’ll be looking at right now should be the posts.js file under the routes directory:

import Ember from "ember";

export default Ember.Route.extend({});

If you run ember serve and then fire up the browser and go to /posts you should see that everything works, there is just nothing to display right now.

Loading Model data

As I mentioned above, one of the responsibilities of the Route is to provide the template with data.

We can do this be implementing the model hook of the Route object. The easiest way of doing this is to simply return an object of data items:

import Ember from "ember";

export default Ember.Route.extend({
  model: function () {
    return [
      {
        title: "Hello world",
        body: "Nulla dolor ipsum, dapibus sed sodales sed, molestie eu metus.",
      },
      {
        title: "My first post",
        body: "Curabitur pellentesque enim et purus venenatis, ac gravida erat euismod.",
      },
    ];
  },
});

Now if you add the following code to your posts.hbs file you should see the data rendered in the browser:

<ul>
  {{#each post in model}}
  <li>{{post.title}}</li>
  {{/each}}
</ul>

Now of course you will not want to hardcode the data into your application because that would make the application pretty useless!

Typically you are going to load the data using an Ajax request or through a model layer such as Ember Data. However, for now we will simply work with hardcoded data to understand what’s going on under the hood. There is no point in trying to run before we can walk!

Choosing the Controller and the Template

The Route is also responsible for passing data to the Controller and for rendering the Template.

As I mentioned earlier, by default, Ember will make some assumptions about the names of the Controller and Template to use. If Ember can’t find these files, it will automatically generate them in-memory at run-time.

However, you might want to use a Controller or a Template that does not fit with Ember’s naming conventions. In order to do that, you can specify it in the Route class.

To use a controller that is different to the Ember default you can specify the controllerName property:

export default Ember.Route.extend({
  controllerName: "article",
});

If you want to use a different template, you can implement the renderTemplate hook:

export default Ember.Route.extend({
  renderTemplate: function () {
    this.render("highlightedArticle");
  },
});

Transitioning and Redirecting

If you want to transition or redirect you can deal with this in the Route by hooking on to one of the hooks.

Firstly you can transition before the model has been loaded using the beforeModel hook:

export default Ember.Route.extend({
  beforeModel: function () {
    this.transitionTo("login");
  },
});

Alternatively you can transition after the model has loaded if you need to determine whether to transition or not based upon the model instance:

export default Ember.Route.extend({
  afterModel: function (posts, transition) {
    if (posts.get("length") === 0) {
      this.transitionTo("login");
    }
  },
});

Conclusion

One of the great things about Ember is the fact that a lot of the functionality will work straight out-of-the-box. It’s surprising how little code you actually need to write to get your Ember application up and running.

However, this is obviously a double-edged sword. Whilst working within these constraints makes for a wonderful experience, I’m sure everything won’t be so pretty if you try to stray from the beaten path.

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.

Philip Brown

@philipbrown

© Yellow Flag Ltd 2024.