Computed properties in controller in Ember

3.3k views Asked by At

I'm a raw beginner with Ember. The app is a sleep tracker. What I'm trying to build right now is the average number of hours slept and napped, over the past N days.

To calculate the average, I believe I want to add a computed property on the controller. I don't have a model yet, because the app is so raw.

Here is my current code:

// app/routes/home.js
import Ember from 'ember';

let events = [
  {
    "dow": 5,
    "durationInSeconds": 29280,
    "endAt": 1471087260000,
    "startAt": 1471057980000,
    "timezone": "America/Montreal"
  },
  { ... }
]

export default Ember.Route.extend({
  model() {
    return events.sortBy("startAt").reverse();
  }
});

// app/controllers/home.js
import Ember from 'ember';

export default Ember.Controller.extend({
  averageNapDuration() {
    console.log("model: %o", this.get('model'));
    return 0;
  },

  averageNightDuration() {
    // TODO
  }
});

// app/templates/home.hbs
<table>
  ..
  <tfoot>
    <tr>
      <td scope="row" colspan="3">Average nap</td>
      <td class="duration">{{format-duration averageNapDuration}}</td>
    </tr>
    <tr>
      <td scope="row" colspan="3">Average night</td>
      <td class="duration">{{format-duration 22680}}</td>
    </tr>
  </tfoot>
</table>

My format-duration helper function does a console.log of the received values. When it's time to display the average, format-duration receives a function instead of a value.

I also failed to see the console.log call in the controller.

In the Handlebars template, I tried using:

{{format-duration averageNapDuration() }}

but this returns a syntax error:

Error: Parse error on line 48:
...">{{format-duration averageNapDuration()
-----------------------^
Expecting 'CLOSE_RAW_BLOCK', 'CLOSE', 'CLOSE_UNESCAPED', 'OPEN_SEXPR', 'CLOSE_SEXPR', 'ID', 'OPEN_BLOCK_PARAMS', 'STRING', 'NUMBER', 'BOOLEAN', 'UNDEFINED', 'NULL', 'DATA', 'SEP', got 'INVALID'

As another test, I changed my controller to use a computed property:

averageNapDuration: Ember.computed.sum('@each.durationInSeconds')

This time, the format-duration says it received 0, which indicates to me, that the template is at least talking to the controller correctly.

Where can I find examples of computed properties on filtered arrays? What must I change in the code above to calculate the sum of an integer?

1

There are 1 answers

2
Ember Freak On BEST ANSWER

This throws parse error.

{{format-duration averageNapDuration() }}

You can't call function in helper arguments. the below will work fine.

{{format-duration averageNapDuration }}

Your controller would be like,

import Ember from 'ember';

export default Ember.Controller.extend({
    averageNapDuration: Ember.computed('model', function() {
        console.log("model: %o", this.get('model'));
        //You can calculate avg nap duration and return the result
        return 0;
    }),
    //this computed property will be called for every durationInSeconds property changes
    averageNightDuration: Ember.computed('[email protected]', function() {
        //You can calculate avg night slepp duration and return the result
    })
});

If we use the dependant key as model.[] then computed property will be called for every time event is added/removed and changed to brand new different array.

If we use the dependant key as [email protected] then computed property will be called for every time durationInSeconds property changes and also for every event time event is added/removed to model. and entire model property is changed to brand new different array.

Ember guides link for computed properties and Computed Properties and Aggregate Data will explain better.