I recently spent some time converting a medium-sized Javascript application using Ember.js to AngularJS, here are a few thoughts about the migration.

First of all, why migrate at all?

The Ember.js code is based on a 0.9x version and as Ember.js is approaching 1.0, I was growing increasingly nervous at the thought of porting the application to 1.0 considering the number of breaking changes that the new version contains (nothing wrong with that, it’s the risk you take when you use a pre-release version). Since there would be major work involved, I thought that taking another look at Angular wouldn’t hurt.

Overall, Angular is a much more extensive framework than Ember. On top of offering a binding/MVC framework, Angular supports:

  • Modules. You pick and choose which functionalities you want and you can create modules of your own code as well.
  • Injection and testability. This should come as no surprise since one of Angular’s main developers, Misko, is a regular poster on Google’s testing blog.
  • Support for partials and inclusion of templates. This is another thing I really missed with Ember.js, which offers no easy way to break down your HTML templates into smaller, more manageable files. Angular allows you to do this either through routes and partials or straight inclusion of files.
  • Documentation. While the Ember.js documentation is fairly large, I found it very unorganized and I often resorted to searching the page to find what I need. In contrast, Angular’s documentation follows a clean structure where each page contains a full example of the concept being explained (a trend I wish more documentations followed: with this kind of model, it doesn’t matter much if your documentation is well written as long as the code samples work. Also, I really like the way they present the code in these samples, with individual panels for the HTML, Javascript and any other file you might need).

There are a lot of fundamental differences in philosophy between Ember.js and Angular, and one of the most important ones is how they handle templates.

Ember.js follows the more classical way of making you write files that look like HTML but are not really since they are littered with directives that drive the template engine:

    {{#each people}}
  • Hello, {{name}}!
  • {{/each}}

In contrast, Angular template files use proprietary HTML attributes which will be processed by its compiler to modify the DOM:

  • Hello, {{person.name}}!

I have found that Angular’s approach makes it easier to debug your templates because the HTML that you are inspecting is exactly what it looks like after expansion. Reading Ember.js processed templates is made harder by the fact that they are littered with magic Ember identifiers (e.g. “id="metamorph-34-start"“).

Data binding is performed very differently between the two frameworks. Ember.js makes you wrap all the objects that are part of your model so that it can monitor them. Despite offering theoretical great power, updating Ember objects is still fraught with annoyances:

  • You need to remember to call the setter: object.set('foo', newValue). Assigning this field directly will not fail but will cause some data binding to not work.
  • Cascading updates are being executed right away. While this seems like a good idea in theory, the practice is very different since there are times where I want to do batch updates to my objects before telling my UI to update itself. I ended up adding boolean flags to manually prevent my listeners from automatically triggering until my model was ready, which seems to defeat the purpose of data binding.

Angular’s data binding is much more straightforward (you just update the objects of your model directly) and “most of the time”, it works. There are times where you will have to tell Angular to perform its updates, but these are rare. See this very interesting explanation from Misko on StackOverflow.

Ember’s data binding is also magic is a few more ways. You can bind values together (for example, defining that a “full name” is made of “first name” and “last name” by declaring dependencies between these fields) and you declare these by adding “Binding” to the end of the variable. This takes a little to get used to. Bindings at the template level are pretty awkward too, especially for attributes:

  <img {{bindAttr alt="altText"}} />

  <img alt="{{altText}}" />

I had a few other items to cover in this comparison but I’ll stop here, except for one last point: IDEA’s Javascript support is light years ahead of Eclipse and a joy to work with.

Overall, I have to say that I am enjoying working with Angular a lot more than I ever did with Ember, and between the credentials of both the company and the engineers driving Angular, the vibrant community (the mailing-list gets about fifty emails every day), the high quality documentation and support and the modern concepts it supports (modularity, testability, injection), it’s clear to me that Angular has a tremendous amount of momentum and is bound to become the defacto standard with which Javascript single page applications are written in the future.