Ember.js: three ways to declare computed properties and observers

Posted by Kevin Soltysiak on June 10, 2015 Topics: ember.js, ES2015, and ES7

In Ember.js, computed properties let you declare functions as properties. This is most useful when you have properties that depend on other properties: you create one by defining a computed property as a function, which Ember will automatically call when you ask for the property, and you supply which properties this function depends on.

You can then use it the same way you would any normal, "static" property. Computed properties will also observes the properties they depend on, and will be recomputed when they change. You no longer have to manually make sure everything is in sync.

In the same spirit, you can also declare observers: functions that will be called when the properties they observes change.

As of today, there is three different ways to declare computed properties/observers: via prototype extension, Ember.computed/Ember.observer, or using ES7 decorators.

Function prototype extension

This is probably the most known and most used way of declaring computed properties and observers. Ember.js "enhances" many javascript native objects such as Array or Function (yes, a function is an object in javascript) either for performance or syntactic reasons. One of those allows you to call property on a function to turn it into a computed property (or observes for an observer):

However, while still being used in the official guides, this way is no longer recommended. You might have seen that most examples by core team members uses another syntax...

Ember.computed & Ember.observer

You probably know Ember.computed mostly as a namespace for helpers such as Ember.computed.alias or Ember.computed.none, but it is first and foremost the function allowing you to declare a computed property.

Under the hood, the prototype extensions seen before calls Ember.computed for computed and Ember.observer for observers. This has always been the recommended syntax for third-party library authors, since they have no guarantee that prototype extensions will be enabled.

As of today, this is how you should write your computed properties and observers. That being said, if you like to experiment, read on.

ES7 decorators

ES6 is far from being available in all browsers that ES7 is already being worked on. Yehuda Katz has proposed a mechanism for decorators that you can read here. I suggest you read it, but in short, it allows you to "annotate" your objects to "enhance" them.

An Ember CLI addon, ember-computed-decorators allows you to test this today, thanks to Babel. Your computed properties/observers would know look like this:

I think this looks pretty great. It will take some time before the decorator proposal gets stabilized though, so I would not recommend using it in production apps today and keep using Ember.computed and Ember.observer. Just keep in mind that this might be the syntax we will be using in a few years :)