0
votes

I have a model with the property "fees"

fees: DS.hasMany('fee')

and a fee model with the property "amount"

amount: DS.attr('string')

in my controller I want a computed property that adds up all of the fee amounts, so I have this

feeTotal: Ember.computed('model.fees.@each.amount', function() {
  var total = 0;
  this.get('model').get('fees').forEach(function(fee) {
    total += Number(fee.get('amount'));
  });
  return total;
})

This will compute the fee initially, and recompute when a new fee is added, but it doesn't recompute when a fee amount is changed. For example, changing the following input field will update the amount but not the computed total.

{{#each model.fees as |fee|}}
  {{input value=fee.amount type="number" placeholder="Fee Amount"}}
{{/each}}

Am I missing something in the way the computed property is written?

1
does it work if you change DS.attr('string') to DS.attr('number')? - Christopher Milne
no, it doesn't change the result. The problem is really that it doesnt recognize a change in the property, regardless of it being a string or number. - cswright
Code looks fine to me, although I saw question here mentioning similar problem after upgrading ember. If you became really desperate you could try Ember 2.0. Only tip I can provide is that you can compute sum and similar things with reduce and basically make computed function one-liner. - Keo
I've put your code in Ember Twiddle and it seems to work just fine. Maybe you're not displaying feeTotal in your template? Computed properties only get calculated when their value is requested, like in a template or using get(). - Jon Koops
To clarify here is the code I wrote: gist.github.com/jonkoops/063663240a76de9e65a2 - Jon Koops

1 Answers

0
votes

You should add 'model.fees.length' property to update totalAmount after adding of new fees.

Ember.computed('model.fees.length', 'model.fees.@each.amount', function() {...});

I have some ideas that you can try:

-bind fee model to your base model with DS.belongsTo()

-save fee after changing its value

//template:
<ul>
  {{#each fees as |fee|}}
    <li>
      {{fee.amount}} - {{input type="number" value=fee.amount}} <button {{action 'save' fee}}>Save</button></li>
  {{/each}}
</ul>

//controller
actions: {
  save(fee) {
    fee.save();
  }
}

-watch for 'dirty' values

Ember.computed('model.fees.length', 'model.fees.@each.amount', 'model.fees.@each.isDirty', function() {...});