Computed property not recalulating on model save()


#1

Hi,

I have a computed property defined in the application controller such as this:

totalAmount: computed('model.[]', function () {
	return this.get('model').reduce((previousValue, item) => {
		return parseFloat(item.get('amount')) + previousValue;
	}, 0)
}),

The model (item) is as follows with a one to many relationship with categories (validations constant exluded here for brevity):

export default DS.Model.extend(Validations, {
   description: DS.attr('string'),
  date: DS.attr('date'),
  amount: DS.attr('number', {defaultValue: 0}),
  isExpense: DS.attr('boolean', {defaultValue: true}),
 category: DS.belongsTo('category'),

});

and the category model

export default DS.Model.extend({
  name: DS.attr('string'),
  items: DS.hasMany('item')
});

In the controller, there is an addNewItem method which creates the record, validation is performed by ember-cp-validations

There is also a saveItem method which is passed the above record to persist to the database.

While the computed property totalAmount recalculates when a record is destroyed, it’s not updating when I add a new item. I suspect this is because I am saving the category relationship - it was fine before I added this. Have looked at the DS.PromiseObject (not sure if this is the correct approach!), but am struggling to make this work.

Hope you can help!

Many thanks in advance.


#2

What is the model hook in your route actually returning?


#3

Hi - it’s returning all of the items

…routes/application.js

model () {
   return this.store.findAll('item');
}

#4

Ok, so model hook should be returning a “live updating” array, so that’s good (I asked because if you were using ‘query’ instead the query result wouldn’t be updated with new records, common tripping point).

One thing that I noticed is that in your CP you’re just observing the array ([]) but you’re actually looking at each item’s amount in addition to just the array state. That may not be what’s causing your issue but it’s worth keeping in mind that if you wanted totalAmount to update anytime an item’s amount changed you’d want to make sure you’re observing the amount on each property:

totalAmount: computed('model.@each.amount', function () {
	return this.get('model').reduce((previousValue, item) => {
		return parseFloat(item.get('amount')) + previousValue;
	}, 0)
}),

Also can you clarify what you mean by this (where/how are you saving category, why you suspect this might be the issue)?

I suspect this is because I am saving the category relationship - it was fine before I added this.


#5

Hi @dknutsen - this is great - thank you!!! I only suspected that saving the relationship might be the cause of an issue but clearly it was not (just ignore me!). While I’m here the other thing that’s frustrating with this simple model is that the date is not being passed to the (Django) backend, it’s just being passed null. Is there a simple fix for that?


#6

Yeah CPs can be tricky, even a simple typo in your observer string can really throw things off :grimacing:. I think it’s a common pain point. In the future though we’ll have tracked properties so hopefully a lot of that stuff will be unnecessary!

As for the date… your model looks fine… I’d check that before you do the save it’s actually recording a valid date on the model (you can look at the record in ember inspector or set a breakpoint somewhere). Otherwise you could play around with a custom date transform and see if you can figure out why it’s null, but my guess is it’s happening before the serializer layer and it’s never getting properly set on the record…


#7

Hi - many thanks for getting back. I’ll look again at the date issue. Many thanks again.