Updating State Immutably
Apply immutable updates to signal state.
Updating State Immutably is a free Angular Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Angular Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Immutability
Signals detect change by reference. If you mutate an array or object in place, the reference stays the same and dependent computed() signals may not recompute. Always produce a new reference.
The Mutation Trap
Pushing into an existing array mutates it without changing the reference. Avoid this.
// BAD: mutates in place, reference unchanged
this._items.update(list => { list.push(item); return list; });Spread for Arrays
Create a new array with the spread operator so the reference changes and consumers re-run.
// GOOD: new array reference
this._items.update(list => [...list, item]);Removing Items
Use filter() which returns a brand-new array, leaving the original untouched.
removeItem(id: string) {
this._items.update(list => list.filter(i => i.id !== id));
}Updating One Item
Use map() to return a new array, spreading the matched object into a fresh copy so the inner reference also changes.
markDone(id: string) {
this._items.update(list =>
list.map(i => i.id === id ? { ...i, done: true } : i));
}Spread for Objects
For object state, spread the previous object and override the changed fields. Nested objects need their own spread too.
private _profile = signal({ name: '', address: { city: '' } });
setCity(city: string) {
this._profile.update(p => ({ ...p, address: { ...p.address, city } }));
}set With Fresh Value
When replacing state entirely, set() with a new object is naturally immutable because you provide a new reference.
reset() {
this._profile.set({ name: '', address: { city: '' } });
}Why computed Depends On It
Because computed read models depend on the signal's reference, immutable updates guarantee they recompute. A mutation that keeps the same array reference can silently leave totals and filters stale.
Helper Patterns
Extract small pure helpers for common transforms to keep store methods readable and consistent.
const upsert = (list: Item[], item: Item) =>
list.some(i => i.id === item.id)
? list.map(i => i.id === item.id ? item : i)
: [...list, item];
save(item: Item) { this._items.update(l => upsert(l, item)); }Deep Nesting Caution
Deeply nested state means many spreads. If updates get painful, flatten the state shape or split it into multiple signals so each update touches a small slice.
Immutability Aids Debugging
Because each update produces a new reference, you can compare snapshots over time, log previous vs next state, and reason about changes without worrying about hidden in-place edits.
Quick Check
Test your grasp of immutable signal updates.
Recap
You learned immutable update patterns: spread for arrays and objects, map/filter for edits and removals, fresh references via set, and why reference equality makes immutability essential for correct reactivity.
Frequently asked questions
Is the “Updating State Immutably” lesson free?
Yes — the full text of “Updating State Immutably” is free to read here on the web, and the Angular Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Angular Academy course, upgrade to CoddyKit PRO.
What will I learn in “Updating State Immutably”?
Apply immutable updates to signal state. You practise Angular Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Angular Academy?
No prior experience is required. Angular Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Updating State Immutably” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Angular Academy lesson?
Yes. Every Angular Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Signal Stores in Services
- Deriving State with computed
- Updating State Immutably
- Connecting Signals and RxJS