Computed Signals
Computed signals are read-only signals that derive their value from other signals. When any dependency changes, the computed signal automatically recalculates.
A computed signal is a read-only signal whose value is derived from other signals. Like an Excel formula โ when input cells change, the formula result updates automatically.
"Computed = calculator โ input badlo toh output apne aap badal jayega."
import { signal, computed } from '@angular/core';
const firstName = signal('Hyderabadi');
const lastName = signal('Biryani');
// Computed signal โ auto-updates when firstName or lastName change
const fullName = computed(() => `${firstName()} ${lastName()}`);
console.log(fullName()); // 'Hyderabadi Biryani'
firstName.set('Chennai');
console.log(fullName()); // 'Chennai Biryani' โ auto-updated!
Key properties of computed:
- Read-only โ you cannot .set() or .update() a computed signal. It only reads from its dependencies.
- Lazy โ only recalculates when someone reads the value (or when used in template/effect).
- Cached โ stores the last computed value. If dependencies haven't changed, returns cached value instantly.
- Automatic dependency tracking โ Angular automatically tracks which signals are read inside the computed function.
Creating a computed signal is simple โ call computed() with a function that reads other signals.
import { signal, computed } from '@angular/core';
// Source signals
price = signal(250);
quantity = signal(2);
discountPercentage = signal(10);
// Derived values โ computed signals
total = computed(() => price() * quantity());
discountAmount = computed(() => total() * discountPercentage() / 100);
grandTotal = computed(() => total() - discountAmount());
console.log(grandTotal()); // 450 (500 - 50)
Angular automatically tracks which signals you read inside computed(). When any of those signals change, the computed value is marked as "dirty" โ it will recalculate the next time someone reads it.
"computed = formula โ dependencies automatically track hoti hai."
TypeScript inference:
price = signal(250); // Signal<number>
total = computed(() => price() * quantity()); // Computed<number>
name = signal('Biryani');
uppercase = computed(() => name().toUpperCase()); // Computed<string>
isReady = signal(false);
message = computed(() => isReady() ? 'Ready!' : 'Loading...'); // Computed<string>Computed signals can handle any transformation logic โ filtering, mapping, reducing, sorting.
import { signal, computed } from '@angular/core';
// Source data
biryanis = signal<Biryani[]>([
{ id: 1, name: 'Chicken Biryani', price: 250, category: 'Non-Veg' },
{ id: 2, name: 'Mutton Biryani', price: 350, category: 'Non-Veg' },
{ id: 3, name: 'Veg Biryani', price: 200, category: 'Veg' },
{ id: 4, name: 'Egg Biryani', price: 220, category: 'Non-Veg' },
]);
selectedCategory = signal('All');
// Computed: filter by category
filteredBiryanis = computed(() => {
const category = selectedCategory();
return category === 'All'
? biryanis()
: biryanis().filter(b => b.category === category);
});
// Computed: total price
totalPrice = computed(() =>
filteredBiryanis().reduce((sum, b) => sum + b.price, 0)
);
// Computed: average price
avgPrice = computed(() =>
biryanis().length > 0
? Math.round(biryanis().reduce((s, b) => s + b.price, 0) / biryanis().length)
: 0
);
// Computed: sorted by price
sortedByPrice = computed(() =>
[...biryanis()].sort((a, b) => a.price - b.price)
);
"Jitna complex ho sake โ computed handle karega. Filter, map, reduce โ sab kuch."
Performance note: Computed signals cache their results. If dependencies haven't changed, the computation does NOT re-run โ it returns the cached value. This makes them efficient even with expensive operations.
Computed signals can form chains โ one computed depends on another, which depends on another.
import { signal, computed } from '@angular/core';
// Base signals
price = signal(500); // Base price per item
quantity = signal(2); // Quantity
// Level 1 computed
subtotal = computed(() => price() * quantity()); // 500 ร 2 = 1000
// Level 2 computed โ depends on Level 1
tax = computed(() => subtotal() * 0.05); // 5% tax = 50
// Level 3 computed โ depends on Level 2
total = computed(() => subtotal() + tax()); // 1000 + 50 = 1050
// When price changes:
price.set(600);
// Automatically: subtotal = 1200 | tax = 60 | total = 1260
"Chain = domino effect โ ek gira toh sab girte hai, magar Angular sirf wahi recompute karta hai jo actually change hua."
Smart recomputation: Angular uses a dependency graph. When a base signal changes, Angular knows EXACTLY which computed signals depend on it and only recalculates those. Unaffected branches are skipped.
// If price changes:
// โ subtotal recalculates (depends on price)
// โ tax recalculates (depends on subtotal โ which changed!)
// โ total recalculates (depends on tax โ which changed!)
// But if category filter changes:
// โ filteredBiryanis recalculates
// โ totalPrice recalculates
// โ avgPrice stays cached (no dependency on filter)
// โ sortedByPrice stays cachedThere are three ways to derive values in Angular templates. Computed is almost always the best choice.
| Method | Cached? | Re-runs | Best for |
|---|---|---|---|
| computed() | โ Yes | Only when dependencies change | Derived state |
| Pure Pipe | โ Yes | When input reference changes | Transformations in templates |
| Method | โ No | Every change detection cycle | Event handlers only |
// โ BAD โ Method called in template runs EVERY CD cycle
get fullName() { return this.first() + ' ' + this.last(); }
// Template: {{ fullName }} โ runs 100s of times!
// โ ๏ธ OK โ Pipe runs when input reference changes
// {{ value | myPipe }} โ only when 'value' changes
// โ
BEST โ Computed runs ONLY when dependencies change
fullName = computed(() => this.first() + ' ' + this.last());
// Template: {{ fullName() }} โ cached, efficient
"Computed = smart (cache), Pipe = medium, Method = dumb (always runs)."
Rule of thumb:
- Need derived state from signals? โ computed()
- Need to transform data in template? โ Pipe (or computed if already a signal)
- Need an action on button click? โ Method (not for display)
Key Takeaways
- โ computed() derives value from other signals โ like Excel formula
- โ Read-only โ no .set() or .update(), only reading with ()
- โ Auto-tracks dependencies โ reads signals inside computed function
- โ Cached โ returns cached value if dependencies haven't changed
- โ Chainable โ computed depends on computed, forms dependency graph
- โ Better than methods โ computed only re-runs on dependency change
Want to track your progress?
Log in to save your place and pick up where you left off.
Progress track karna chahte ho?
Login karo apni progress save karne ke liye aur jahan chhoda tha wahan se shuru karo.
Login