
Learn Angular Signals Writable, Computed, and Effects Explained
A clear guide to Angular Signals, including writable signals, computed signals, and effects, with syntax and examples for modern Angular development.
Learn About Angular Signals
In the following technical article, I will share my real-time knowledge about Angular Signals.
What are Signals in Angular?
In Angular, signals are reactive primitives that monitor or track changes in an application and notify interested consumers.Before Angular version 16, you would declare a variable like:
name: string = '';and rely on zone.js for change detection. With signals, there is no dependency on zone.js; they automatically track changes and notify consumers.
Here is the syntax for a signal in Angular:
name = signal<string>('');Here:
- signal() is a function used to create a signal with type string.
- string is the type of the signal, which is optional.
- '"" is the initial value.
Types of Reactive Primitives in Angular
There are three types of reactive primitives:- Writable Signals
- Computed Signals
- Effects
Writable Signals
Writable signals are reactive primitives that provide an API for updating values directly. To create a writable signal, use the signal() function with an initial value:count = signal(0);
or
count: WritableSignal<number> = signal(0);Binding a signal to the template:
<p>{{ count() }}</p>Output:
0
0If you call it without parentheses, it will display the signal object.
Changing the value of writable signals
To set a value, we have the set() method:count.set(10);
<p>{{ count() }}</p>Output:
10Updating the value of writable signals
To update the value, we have an update() method:count.update((val) => val + 1);Output:
11
11Computed Signals
Computed signals are read-only signals whose values cannot be set or updated directly. They derive their values from other signals.Syntax:
count = signal(0);
doubleCount = computed(() => count() * 2);Here,
doubleCount depends on count. When count changes, doubleCount updates automatically.
Since computed signals are read-only, attempting to update them directly will cause a compilation error:
doubleCount.set(10);
// Error
doubleCount.update(val => val + 1); // ErrorEffects
Signals notify consumers when their values change. An effect is an operation that runs whenever one or more signal values change.Syntax:
effect(() => { this.signal_name();});Notes:
- Effects always run at least once.
- The best place to use an effect is inside the constructor.
- Effects execute asynchronously during the change detection process.
- Effects are appropriate only in specific situations.
Example:
import { signal, computed, effect } from '@angular/core';
// state
const n1 = signal(1);
const n2 = signal(2);// derived
valueconst sum = computed(() => n1() + n2());
// side effecteffect(() => {
console.log('Sum:',sum());
});// update valuen1.set(5);Here:
- sum automatically recalculates when n1 or n2 changes.
- effect runs whenever sum changes.
- Updating n1 logs the new sum.
Based on my personal experience as a full-stack developer, signals make development easier. They are especially useful in zoneless Angular applications and improve performance with better state management for UI updates.