Angular 9: Computed Signals
easy⏱ 5 mincourseangular
computed() auto-tracks its dependencies
const total = computed(() => price() * quantity()); reads two signals inside its function. Angular notices exactly which signals were read during that run and subscribes the computed signal to only those — no manual dependency list, unlike some other frameworks' derived-state APIs. If price or quantity later changes, total is marked stale; the next time something reads total(), it recomputes once and caches the new result.
const price = signal(10);
const quantity = signal(3);
const total = computed(() => price() * quantity());
total(); // 30, computed once and cached
total(); // 30, returned from cache, no recompute
quantity.set(5);
total(); // 50, recomputed because a dependency changed
computed() vs a plain getter
A TypeScript getter — get total() { return this.price * this.quantity; } — looks similar in a template ({{ total }}), but it has no memory: every single read re-runs the whole function body, whether or not the inputs changed. In a large template read many times per render, that's wasted work. computed() caches until a real dependency change invalidates it, which is cheaper and also gives you a genuine signal you can pass around, read in effect(), or compose into other computed()s.
Build ShoppingCart
Declare items = signal<CartItem[]>([...]). Add total = computed(() => this.items().reduce((sum, i) => sum + i.price * i.quantity, 0)) and itemCount = computed(() => this.items().reduce((sum, i) => sum + i.quantity, 0)). Display both in the template alongside the item list.