---
layout: post
title: Your Ember app is a click away from home
tags: [ ember, development ]
published: true
---
I've been having some time to explore Ember.js lately and I wanted to learn by
doing instead of just reading about it. So bear with me as this might probably
require some updating in the future. This is a result of trial and error and I
thought of making the Ember learning curve a little easier and share this tip.
So I've been trying to build a simple application that manages pictures. I
started the good ol' fashioned way of manually calling all the scripts and
declaring all the templates from the index page, for argument's sake. I would
much rather have something like
[Iridium](http://github.com/radiumsoftware/iridium) to help with my development
process but I had faced some trouble with it before.
My first step: list of pictures
-------------------------------
The first thing that came to my mind was to have a list of pictures and allow
the user to add a new one by clicking on a link that would transition to
something like `/pictures/new`. In the pictures list template I would have
something like:
{% highlight html %}
Images
{%raw%}{{#each image in controller}}
{{image.title}}
{{/each}}
New image
{%endraw%}
{% endhighlight %}
The link in the paragraph goes to the route transition in "root". Let me give
you the router so you can better understand what I'm saying:
{% highlight javascript %}
Exhibit.Router = Ember.Router.extend({
root: Ember.Route.extend({
, index: Ember.Route.extend({
route: "/"
, connectOutlets: function(router, context) {
router.get("applicationController").connectOutlet("images", Exhibit.Image.all());
}
, newImage: Ember.Route.transitionTo("newImage")
})
, newImage: Ember.Route.extend({
// ...
})
})
});
{% endhighlight %}
Inside the `index` route, the `newImage` path points to the `newImage` route
which will print a form.
The challenge: Going back home
------------------------------
At this point in time, I was curious as to the possibility of aborting the
process of creating a new image and simply going back home and start over. As I
was learning, I realized that actions in the templates point to routes in the
router as a way to acknowledge an application state change. I faced the
challenge of wanting to leave the form and go back and not being able to
do it.
I recalled that actions should be defined in the state (the route) the
application is in. Clicking on the `newImage` link transitions my app to the
`root.newImage` state. So I thought of doing something like this in the router:
{% highlight javascript %}
Exhibit.Router = Ember.Router.extend({
root: Ember.Route.extend({
, index: Ember.Route.extend({
// ...
})
, newImage: Ember.Route.extend({
route: "/new"
, connectOutlets: function(router, context) {
// connect the outlet
})
===> , goHome: Ember.Route.transitionTo("root.index")
})
})
});
{% endhighlight %}
This looks rather trivial and probably won't make the point alone. What I
thought at the time when I wrote this was _should I really need to write this
transition in every single route?_ After all, going back home should be
possible for every action, every state in the app.
The solution: Use the state machine
-----------------------------------
After some trial and error, I ended up with this:
{% highlight javascript %}
Exhibit.Router = Ember.Router.extend({
root: Ember.Route.extend({
=> goHome : Ember.Route.transitionTo("root.index")
, index : Ember.Route.extend({ /* ... */ })
, newImage : Ember.Route.extend({ /* ... */ })
})
});
{% endhighlight %}
Since the router is a state machine, when defining the `root` route, I'm able
to add state changes there that will be inherited for every sibling state in
that tree. Both `index` and `newImage` and all the routes that are defined in
`root` will have this state change available.
This was a finding for me as I have never grasped the concept of state machines
like this.