Computed property does not update when nested dependent property changes if computed setter is called

Twiddle: https://ember-twiddle.com/706dc2003c71ffee87e85a87f467b1ef?numColumns=2&openFiles=controllers.application.js%2Ctemplates.application.hbs

I have a computed property (comp2) which depends on another computed property(comp1) which depends on a property, foo, in the controller. I also have another property valueOfComp2 in the controller which, for the sake of simplicity, is updated with the value of comp2 through update method

During init, I set comp2 to some value. After this, any update to foo will not reflect in comp2 or valueOfComp2

If I access comp1 or comp2 directly in the template, then there is no issue. If foo is declared as a dependency in comp2, then there is no issue. If I access comp1 at least once in update method, then everything works.

I sort of understand why this happens. But, why does it break only when there is a setter involved?

I think the problem is that if you set comp2 on init, it never has to calculate comp1 because it caches the comp2 value, but if you don’t set comp2 it gets comp1 and then comp1 will recalculate whenever foo changes. Because comp1 is only used as a dependency of comp2 and never used directly if you short-circuit the comp2 calculation by setting it you never get comp1 and because computed properties don’t calculate/recalculate unless they are fetched at least once it never gets calculated and therefore never gets recalculated.

IMO this is an indication that this data flow could probably be refactored to be cleaner and less confusing. That said the computed property optimizations can be tricky and a little confusing, so it’s nice that they will be replaced with tracked properties in the future and hopefully this kind of thing will happen less.

2 Likes