Things I wish someone had told me when I was learning Ember.js

  1. Learn the nuances between a route and a resource.  A resource is a definition of a thing. a route is something that thing can do. Nesting resources just means that you may have a dependency or parent / child relationship.
  2. If something doesn’t need to interact with any other controller, view, or component, it should be a component to maintain your sanity.
  3. Make a /packages/ directory, one for each namespace.  Grouping files by name helps enforce the naming conventions that are all over the place.  Do the same with your sources.  e.g; /packages/application/applicationRoute.js
  4. follow the [namespace][Type] naming convention, so that you can super+p any file by typing it’s namespace. e.g; /packages/application/applicationView.js.  The only exceptions are components due to limitations of the framework. (expects a components folder and a templates/components folder).
  5. Don’t use AMD, CJS, or browserify.  This forces you to work within the conventions of the framework, as all references to other namespaces are available within your declarations in nearly all scenarios (controllers can use needs: [], route actions bubble, view’s have ViewTargetActionSupport mixins available, etc.)  I personally use grunt-neuter.
  6. Think declaratively and reactively about how you want your logic to flow.  An example of this would be defining a ‘currentIndex’ property, and binding to when that index changes via observers or computed properties.
  7. Avoid pub/sub and Ember.Evented as much as you can.  It’s tempting to go the easy route with pub/sub to communicate with other components.  It’s almost universally a bad idea to do this, since there are so many ways to communicate with other parts of your application.
  8. avoid any logic within your templates.  They should be focused strictly on presentation.  Create computed properties on your controllers for defining the state of a view, and use those in if statements if you absolutely must.
  9. don’t use the {{each}} syntactic sugar.  use {{each foo in object}}.
  10. Long names are okay.  You shouldn’t be worried about using computedCurrentIndex vs idx in your definitions.  Think of the other developers who might someday look at this.  Do be that guy who tries to save a few bytes in javascript because they want to eliminate characters.  If you’re not using Uglify already in your grunt toolchain, What the hell is wrong with you?
  11. Treat your javascript as annotated source code, rather than something that gets interpreted.  What gets spit out of uglify doesn’t really impact any of your compiled code; go hog wild.
  12. components are effectively a controller, view, and template without a specific route.
  13. learn how to use the {{render}}, {{#view}} and {{view}} handlebars helpers.   {{render}} is invaluable for partials that may or may not need state. {{#view}} lets you define a yield block in your template or define it inline if need be.   {{view}} can be used for any self contained views you may need to otherwise {{render}} as a partial.
  14. Avoid Ember.Containeras much as you can.  If something cannot be accurately represented within an Ember.Object, try again.  The API is ugly and frankly Ember.Objects give you just about all of the value of them, short of their singleton-like nature (which you can manage with an IIFE and an instance if you must).
  15. this.send('someActionName') within the context of an any controller or route will trigger that action on the controller first, and will bubble.  Use this to your advantage wherever possible.  Need to communicate with routes to a parent of your own? this.send('action') all day long.  Need to be able to override actions in a specific controller or route? just return false from the route, or return true to continue propagation.
  16. jQuery events, short of very specific events or library integrations, should be eliminated in favor or route/controller actions, or handled by a view directly.  This will save you from having to fight the framework later on when you start running into edge cases, dangling references, or worse; zombie events.
  17. Initializers are to be abused whenever possible.  Use them with aplomb. App.Initializer('namespace', initialize: function () {}); – learn what App.delayReadiness() and App.advanceReadiness() are (iOS developer? this is a retain/release cycle for your application’s boot up.  once the retain cycle hits zero, your app is going to start up. Want fixtures? Load them via an initializer and inject them into an Ember.Namespace).
  18. Mixins are great for abstracting common things.  The easiest example would be defining a keyboard event as a mixin, then just executing methods on a “keystrokes” hash in your mixed-in class.   Voila- now every controller or route or what have you can support specific keyboard combinations.   Need to handle pagination? make a consistent mixin api and use it across the application. These are the towels that make you DRY. (groan)
  19. if you find yourself using this._super() pretty much anywhere other than in route.init() or controller.init(), ask yourself long and hard if that inheritance chain can’t be handled in a mixin.  You can probably refactor that for the sanity of everyone.
  20. within the context of a route you can access methods such as this.modelFor('namespace') or this.controllerFor('namespace').  If those elements are currently active, they will return their models or controllers.  Don’t make extra http requests if you can avoid it.
  21. make sure that within a route’s setupController hook, that you set the model on the controller before doing ANYTHING else in that hook. e.g; controller.set('model', model);.  Nothing else will work and it’ll throw an error otherwise. You may see model and content interchangeably used. Use model, not content, it’s getting depreciated.
  22. when you define a resource within your router, you’ll get route.index, route.error, route.loading routes for free, regardless of if you define them (you ought to, especially index).
  23. resources defined in your router have two layers; the base resource (defined as whatever your namespace is + route, controller, or view.) will be loaded FIRST, and then any sub-routes of that resource are loaded.  This means that an App.FooRoute, App.FooController, and App.FooView are loaded before App.FooIndexRoute and App.FooIndexController are set up.  use this.modelFor('foo') to grab the parent’s model if you need data.  Your separation of concerns here is that you want to have the parent resource manage it’s model, and any routes defined under it take care of performing actions with that model.  This one took me ages.
  24. Need to handle view transitions, in the visual sense?  Define a mixin that implements two methods: didInsertElement (be sure to call this._super()!), which in turn calls didAppear.  Each view’s didAppear hook can then set up any transitional properties necessary to animate the view appearing.
  25. in the vast majority of cases, you’ll be binding a lot of classes.  learn the semantics of the {{bind-attr}} helper when it relates to classes.
  26. figure out a good way to bind properties to inline-styles.  You may balk at this, but what do you think jquery.transit, TWEEN, and jquery.animate() do?  now imagine you could databind to those animation flags, using rAF.
  27. when using a component in a template, remember that the assignment is {{my-component INTERNAL_BINDING=EXTERNAL_BINDING}}.  Don’t be afraid to pass in an entire controller’s context if that component is complex.
  28. on that note, don’t be afraid to nest components into one another.  There’s no reason why you shouldn’t do that.


This list is by no means exhaustive, but it’s a good starting point of little tricks i’ve picked up along the way. Have one to add? leave a comment or ping me on twitter @landongn


  1. Hi Landon,

    Thanks for your exhaustive list of tricks and tips, they are very useful.

    One doubt on point 15. How can i access a method in Controller from a Route.

    Thanks jeevi

    • Hey Jeevi.

      Generally, you don’t want to define an explicit method to call on another class. A route shouldn’t really know about the active controllers. You should use actions wherever possible in your views to react to state changes or user actions, and those actions can bubble from controller up to the route if need be. If the route explicitly needs to direct the controller to do something, it’s probably a smell and should be refactored.

      • Hi Jake,

        If you use this.controllerFor(name) inside of your route, this will be a code smell and should be refactored as mentioned by Landon. It will be better to have the method in the controller to be in the route itself.

        Thanks Jeevi

        • I’m not sure I entirely agree on controllerFor being an automatic “code smell”.

          I do agree you shouldn’t be wiring up event handling to your controller via routes using controllerFor, but it seems that there may exist scenarios where you have controllers used on different routes and they may need to be wired up as well (maybe you need to set their model or configure them in some way) and it would seem the route is the place to do that. Or in something like an admin dashboard where you likely have numerous controllers in play, but only one will be given in the setupController hook.

          Definitely open to feedback if you guys disagree.

          Great post!

          • controllerFor, for me anyway, tends to exist when i’ve been working out a solution and haven’t taken the time to refactor that back out into an action on the presenting controller or via controllers.controllerName, by way of the needs: [] prop on the controller.

            Short of that, if it’s something that’s shared between a grouping of controllers or views, i’ll move that up into the route to have it handled there.

        • Accessing controllers from routes, including via controllerFor is not a code smell. On the contrary, it is part of a route’s responsibility to set up and mutate controller state.

          • I don’t necessarily agree with you. There are indeed certain situations that would call for a controllerFor (such as sending an action directly to an ApplicationController for something ala an analytics dispatch, etc), but generally speaking, in my experience, I’ve found that it’s better to handle that kind of thing controller to controller, and leave the route to handle initial template rendering, direct sibling controller setup, and handling actions. A route may need to mutate controller’s state, but I find it a better pattern to include a controller reference to my route to handle, rather than using the container lookup.

            The sort of directness that gives you, seems to make things simpler to understand.

            edit: don’t get me wrong, I think it’s an acceptable thing to do. I just don’t agree with it. YMMV

    • Components are amazing! use them to handle menus, grids of content, pagination, you name it! Generalize whatever you’re building into orthogonal components and I promise you the app architecture will feel much better.

  2. #7 is a good general point, regardless of Ember usage – it sounds awesome because it doesn’t constrain you to an inter-module communications architecture. But that freedom is a terrible thing.

    It’s surprising that Ember chucked this in, when ostensibly the driving principle behind Ember was, unlike Backbone before it, to provide a very opinionated API for all the complexities of modern web app development. Why would they then allow you to opt out of that API? It undermines the whole raison d’être.

    • @Barney

      I don’t think that pub/sub is a bad thing. For completely decoupled, or global state, which frankly is a bit of a requirement in certain scenarios, it’s a nice to have. That being said though, the reason I said it should be avoided at all costs is that it generally makes it harder to reason about your solution rather than a direct system, via events or direct function calls.

      So while I agree that it seems strange for ember to have included Em.Evented in it’s library, it makes sense from an overall ‘framework’ perspective. Batteries Included, if you will.

    • Ember.Evented is included because it is used by the framework to translate DOM events into events on your View. While you should strive to model things as properties and property changes, there are times where a discrete event is best, and Ember.Evented is a great tool for those moments.

  3. Re: #19, using a mix-in is just another way to do inheritance. Ember’s object model is classical OO. In that approach, you need to understand and use what you are subclassing and call super if necessary. This ties into #21. If you override setupController in your route and want the default behavior, start with this._super(controller, model);

  4. While there are a lot of good nuggets on this list, there is also a lot that I think is in the range of controversial to wrong. I don’t have time to make further comments tonight, but I will try to come back this weekend and give some more feedback.

  5. When you are also provide a question such as registering the company for regular business scheme for the accountant to be tuned down so it is less expensive when your contractor.
    The services of licensed contractors used to advocate for over 20 years, as well as the Sahara, I might give homeowners a simple task.
    Consumer fraud is something that you do not have a legal contract with the help of a contractor
    to do.

  6. Once the main contractor just got hired as an additive to limestone prior to the employer as well and reflects a professional school
    bus chimney inspector to inspect properties for potential leveraged buyouts.
    This statement is for them to school bus treat them like you, your
    life. They all look to check on the design of the home renovation project.

  7. Go to your assistance contractor for their business comes close to them.
    This is a great way to incapacitate armies.
    In the meantime you can analyze it and forget the distinction involves post-payment by the IRS could hold you liable to pay for the project will benefit
    the government. Ahmed Wali Karzai to bring the job done.

  8. We contractor are dedicated to the finish outcome is uncertain. I will have a simple easy to find good quality roofing services
    includes many other they offer free estimates. Although you may need a
    roof should last a lifetime limited warranty**, which requires welding
    and re plumb.

  9. I hardly comment, but after looking at a few of the remarks on Things
    I wish someone had told me when I was learning Ember.js | landongn. I do have a few questions for you if it’s okay.
    Is it simply me or do some of the remarks look like
    they are written by brain dead people? :-P And, if you are posting on other social sites, I would like
    to keep up with you. Would you list of the complete urls of your social networking pages like your Facebook page, twitter feed, or linkedin profile?

  10. Getting their color palettes unlicensed contractors of
    Benjamin Moore color called Split Pea. Attendees learned what the contractor understands what you what it is funded by a contractor, concerning the beautification of their work and happy all year long.

  11. Here’s one that just bit me in the ass: Naming your model ‘something-data’. Ember apparently does not like that and it made it impossible to create a custom adapter for that model.

    Had to glean that fact from stack-overflow. No mention of it in the Ember docs and nothing even resembling a reasonable error because of it.


Leave a Comment.