---
title: Custom Ember Computed Properties
teaser: How to refactor your own computed properties in Ember.js.
tags: web,ember,javascript
author: Jason Draper
published_on: 2014-02-14
---

[EmberJS][emberjs] has a lot of features for helping you build a
clean JavaScript interface. One of my favorites is the [computed
property][ember-computed-properties]; Ember
can watch a property or set of properties and when any of those change, it
recalculates a value that is currently displayed on a screen:

```coffeescript
fullName: (->
  "#{@get('firstName)} #{@get('lastName')}"
).property('firstName', 'lastName')
```

Any time the `firstName` or `lastName` of the current object change,
the `fullName` property will also be updated.

In my last project I needed to cacluate the sum of a few properties in an array.
 I started with a computed property:

```coffeescript
sumOfCost: (->
  @reduce ((previousValue, element) ->
    currentValue = element.get('cost')
    if isNaN(currentValue)
      previousValue
    else
      previousValue + currentValue
  ), 0
).property('@each.cost')
```

This works fine but I need to use this same function for a number of different
properties on this controller as well as others. As such, I extracted a helper
function:

```coffeescript
# math_helpers.js.coffee
class App.mathHelpers
  @sumArrayForProperty: (array, propertyName) ->
    array.reduce ((previousValue, element) ->
      currentValue = element.get(propertyName)
      if isNaN(currentValue)
        previousValue
      else
        previousValue + currentValue
    ), 0

# array_controller.js.coffee
sumOfCost: (->
  App.mathHelpers.sumArrayForProperty(@, 'cost')
).property('@each.cost')
```

This removes a lot of duplication but I still have the `cost` property name in
the helper method as well as the property declaration. I also have the
'decoration' of setting up a computed property in general.

What I need is something that works like `Ember.computed.alias('name')` but
allows me to transform the object instead of just aliasing a property:

```coffeescript
# computed_properties.js.coffee
App.computed = {}

App.computed.sumByProperty = (propertyName) ->
  Ember.computed "@each.#{propertyName}", ->
    App.mathHelpers.sumArrayForProperty(@, propertyName)

# array_controller.js.coffee
sumOfCost: App.computed.sumByProperty('cost')
```

This allows me to easily define a 'sum' for a property without a lot of
duplication. In this application I have a lot of similar functions around
computing information in arrays. Being able to easily have one function for
calculation allowed me to easily unit test that function and feel confident that
it would work on any other object. It also simplifies the model or controller a
lot for anyone viewing the class for the first time.

## Update

After publishing this, I was quickly notified that `Ember.computed.sum` has been
[added to Ember as of 1.4][ember-computed-sum]. This is a great addition to the
core, but this example is primarily designed to show an example of how to
refactor your own computed property.

[emberjs]: http://emberjs.com/
[ember-computed-properties]: http://emberjs.com/guides/object-model/computed-properties/
[ember-computed-sum]: http://emberjs.com/api/#method_computed_sum
