Angular

angular/computed-not-effect

Derive state with computed() (or linkedSignal()); never copy one signal into another inside effect().

moderatemanualfe-angular

Why

effect(() => this.total.set(this.price() * this.qty())) runs after the change, so the template first renders the old total and then needs another pass; chains of such effects cause extra change detection, ExpressionChangedAfterItHasBeenChecked errors or loops. Angular's guide calls effects a last resort for syncing with the outside world.

Fix

total = computed(() => this.price() * this.qty()). When the derived value must also be settable by the user (a selection reset when the list changes), use linkedSignal(). Keep effect() for logging, localStorage, a canvas or a third-party widget. This rule is manual because the engine does not read .ts files; the angular-eslint rules and a review of every effect( that calls .set( or .update( find it.

Examples

// bad
total = signal(0)
constructor() { effect(() => this.total.set(this.price() * this.qty())) }
// good
total = computed(() => this.price() * this.qty())

Sources

Facts

Id
angular/computed-not-effect
Severity
moderate
Check
manual a person reviews it; the report lists it as a checklist
Applies to
angular
Only in projects with
angular
Taught by the skill
fe-angular Angular components
Since version
0.1.0

Rule file on GitHub

Read it in the terminal

npx github:dawidolko/frontend-skills explain angular/computed-not-effect