0
0
Angularframework~15 mins

Computed signals for derived values in Angular - Deep Dive

Choose your learning style9 modes available
Overview - Computed signals for derived values
What is it?
Computed signals are special reactive values in Angular that automatically update when their input signals change. They let you create values derived from other signals without manually managing updates. This helps keep your UI and logic in sync effortlessly. Think of them as formulas that recalculate whenever their ingredients change.
Why it matters
Without computed signals, developers must manually track and update derived values, which can lead to bugs and complicated code. Computed signals simplify this by automatically recalculating derived data, making apps more reliable and easier to maintain. This reactive approach improves user experience by ensuring the UI always shows the latest data without extra work.
Where it fits
Before learning computed signals, you should understand basic Angular signals and reactive programming concepts. After mastering computed signals, you can explore more advanced state management patterns and Angular's standalone reactive APIs for building scalable applications.
Mental Model
Core Idea
A computed signal is a reactive formula that automatically recalculates its value whenever its input signals change.
Think of it like...
It's like a recipe that automatically updates the taste of a dish whenever you change any ingredient, without you having to cook it again manually.
Signals (inputs) ──▶ Computed Signal (formula) ──▶ Derived Value (output)
  │                     ▲
  └─────────────────────┘

When any input signal changes, the computed signal recalculates and updates the derived value.
Build-Up - 7 Steps
1
FoundationUnderstanding Angular Signals Basics
🤔
Concept: Signals hold reactive values that notify dependents when they change.
In Angular, a signal is a special object that stores a value and lets other parts of your app react when this value changes. You create a signal with `signal(initialValue)`. When you update the signal, anything that uses it automatically updates too.
Result
You get a reactive value container that triggers updates in your app when changed.
Understanding signals is key because computed signals build on this reactive value concept to derive new values automatically.
2
FoundationCreating Simple Signals and Reading Values
🤔
Concept: You can create signals and read their current value using `.()`.
Example: const count = signal(0); console.log(count()); // prints 0 count.set(5); console.log(count()); // prints 5 Signals hold values and expose them via calling the signal as a function.
Result
You can store and retrieve reactive values easily.
Knowing how to create and read signals is the foundation for building reactive logic and computed signals.
3
IntermediateIntroducing Computed Signals for Derived Values
🤔Before reading on: do you think computed signals update automatically or require manual triggers? Commit to your answer.
Concept: Computed signals automatically recalculate their value based on other signals they depend on.
You create a computed signal with `computed(() => expression)`. The expression uses other signals. When any of those signals change, the computed signal recalculates. Example: const count = signal(1); const double = computed(() => count() * 2); console.log(double()); // 2 count.set(3); console.log(double()); // 6 (auto updated)
Result
Derived values stay in sync automatically without manual updates.
Understanding automatic recalculation prevents bugs from stale data and simplifies reactive code.
4
IntermediateUsing Computed Signals in Angular Components
🤔Before reading on: do you think computed signals can be used directly in templates or only in component code? Commit to your answer.
Concept: Computed signals can be used inside Angular components and templates to reflect derived reactive data.
Inside a component: @Component({ selector: 'app-counter', template: `

Double: {{ double() }}

` }) export class CounterComponent { count = signal(1); double = computed(() => this.count() * 2); } The template automatically updates when `count` changes because `double` is reactive.
Result
UI updates automatically to show derived values without extra code.
Knowing computed signals integrate seamlessly with templates helps build clean reactive UIs.
5
IntermediateAvoiding Unnecessary Recomputations
🤔Before reading on: do you think computed signals always recompute on every change or only when their dependencies change? Commit to your answer.
Concept: Computed signals only recompute when their dependent signals change, optimizing performance.
Computed signals track which signals they read during computation. If none of those signals change, the computed signal returns cached value. Example: const a = signal(1); const b = signal(2); const sum = computed(() => a() + b()); If only `a` changes, `sum` recomputes. If unrelated signals change, `sum` does not.
Result
Efficient updates prevent wasted work and improve app speed.
Understanding dependency tracking helps write performant reactive code.
6
AdvancedHandling Side Effects with Computed Signals
🤔Before reading on: do you think computed signals should contain side effects like logging or HTTP calls? Commit to your answer.
Concept: Computed signals should be pure and side-effect free; side effects belong in effects or other reactive constructs.
Computed signals are meant to derive values only. Putting side effects inside them can cause unpredictable behavior. Instead, use `effect(() => { ... })` for side effects triggered by signals. Example: const count = signal(0); const double = computed(() => count() * 2); effect(() => console.log('Double is', double()));
Result
Clear separation of pure computation and side effects leads to predictable apps.
Knowing this prevents subtle bugs and keeps reactive logic clean and maintainable.
7
ExpertComputed Signals Internals and Change Detection
🤔Before reading on: do you think Angular's computed signals use dirty checking or dependency tracking under the hood? Commit to your answer.
Concept: Computed signals use fine-grained dependency tracking to know exactly when to recompute, avoiding full dirty checks.
When a computed signal runs, Angular records which signals it reads. These become dependencies. When any dependency changes, Angular marks the computed signal as stale. On next read, it recomputes the value. This lazy recomputation avoids unnecessary work. This mechanism integrates with Angular's change detection to update the UI efficiently.
Result
Highly efficient reactive updates with minimal overhead.
Understanding this mechanism explains why computed signals are both fast and reliable in large apps.
Under the Hood
Computed signals work by running their computation function and tracking all signals accessed during that run. These accessed signals become dependencies. When any dependency signal changes, the computed signal is marked as needing recomputation. The next time the computed signal's value is requested, it recalculates by running the function again. This lazy evaluation ensures computations happen only when needed. Angular integrates this with its change detection to update the UI efficiently.
Why designed this way?
This design avoids expensive full checks of all reactive values by tracking exact dependencies. It balances performance and correctness, preventing unnecessary recomputations. Earlier reactive systems used polling or manual subscriptions, which were error-prone or inefficient. Angular's computed signals provide a declarative, automatic, and optimized way to keep derived values up to date.
┌───────────────┐       ┌───────────────┐
│ Input Signal 1│──────▶│               │
│ (e.g. count)  │       │ Computed      │
└───────────────┘       │ Signal        │─────▶ Derived Value
                        │ (formula)     │
┌───────────────┐       │               │
│ Input Signal 2│──────▶│               │
│ (e.g. factor) │       └───────────────┘
└───────────────┘

When Input Signal 1 or 2 changes, Computed Signal marks itself stale.
On next read, it recomputes and updates Derived Value.
Myth Busters - 4 Common Misconceptions
Quick: Do computed signals run their function every time you read them, or only when dependencies change? Commit to your answer.
Common Belief:Computed signals run their function every time you read them, so they are expensive.
Tap to reveal reality
Reality:Computed signals cache their value and only recompute when their dependencies change, making them efficient.
Why it matters:Believing they always recompute can scare developers away from using them, missing out on performance benefits.
Quick: Can you put side effects like HTTP calls inside computed signals safely? Commit to yes or no.
Common Belief:It's fine to put side effects inside computed signals since they run automatically.
Tap to reveal reality
Reality:Computed signals should be pure and side-effect free; side effects belong in effects or other reactive constructs.
Why it matters:Putting side effects inside computed signals can cause unpredictable behavior and bugs.
Quick: Do computed signals update their value immediately when dependencies change, or only when read next? Commit to your answer.
Common Belief:Computed signals update their value immediately as soon as any dependency changes.
Tap to reveal reality
Reality:Computed signals mark themselves stale on dependency change but recompute lazily on next read.
Why it matters:Understanding lazy recomputation helps avoid confusion about when values update and improves debugging.
Quick: Are computed signals a replacement for all state management in Angular? Commit to yes or no.
Common Belief:Computed signals replace the need for any other state management tools.
Tap to reveal reality
Reality:Computed signals are a tool for derived reactive values but do not replace full state management solutions like NgRx or services.
Why it matters:Overreliance on computed signals alone can lead to poor app architecture and scalability issues.
Expert Zone
1
Computed signals track dependencies dynamically during each run, so conditional logic inside the computation can change which signals are tracked.
2
Computed signals use lazy evaluation, meaning they only recompute when their value is requested, not immediately on dependency change.
3
Stacking computed signals (computed depending on other computed) creates a dependency graph that Angular efficiently manages to minimize recomputations.
When NOT to use
Avoid using computed signals for side effects or asynchronous operations; use Angular effects or observables instead. Also, for complex global state management, consider NgRx or other dedicated libraries rather than relying solely on signals.
Production Patterns
In real apps, computed signals are used to derive UI state like filtered lists, formatted dates, or combined flags. They are combined with effects for side effects and signals for base state. Developers often create reusable computed signals for common derived logic to keep components clean.
Connections
Functional Programming
Computed signals embody the concept of pure functions and immutability by deriving values from inputs without side effects.
Understanding pure functions helps grasp why computed signals must be side-effect free and deterministic.
Spreadsheets
Computed signals work like spreadsheet formulas that automatically update when input cells change.
Knowing how spreadsheets recalculate cells clarifies how computed signals track dependencies and update lazily.
Observer Pattern (Software Design)
Computed signals implement a refined observer pattern where dependents subscribe to changes in dependencies.
Recognizing this pattern explains how Angular efficiently propagates changes through reactive values.
Common Pitfalls
#1Putting side effects like logging or HTTP calls inside computed signals.
Wrong approach:const data = computed(() => { fetch('/api').then(...); return someSignal(); });
Correct approach:const data = signal(null); effect(() => { fetch('/api').then(response => data.set(response)); });
Root cause:Misunderstanding that computed signals should be pure and side-effect free.
#2Manually updating derived values instead of using computed signals.
Wrong approach:let doubleValue = 0; count.set(5); doubleValue = count() * 2; // manual update needed everywhere
Correct approach:const doubleValue = computed(() => count() * 2);
Root cause:Not leveraging reactive derivation leads to error-prone and verbose code.
#3Expecting computed signals to recompute immediately on dependency change.
Wrong approach:console.log(double()); count.set(3); // expecting double() to have updated immediately without reading it again
Correct approach:count.set(3); console.log(double()); // recomputes now on read
Root cause:Confusing lazy recomputation with immediate update semantics.
Key Takeaways
Computed signals in Angular automatically derive values from other signals, keeping data in sync without manual updates.
They track dependencies dynamically and recompute lazily, making reactive updates efficient and predictable.
Computed signals must be pure and free of side effects; side effects belong in effects or other reactive constructs.
Using computed signals simplifies UI updates and reduces bugs caused by stale or manually managed derived data.
Understanding computed signals connects to broader concepts like pure functions, observer patterns, and spreadsheet formulas.