--- 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.