Introduction to Signals in Angular
What are signals ?
Signals contains a value , which when changed informs all the other consumers(subscribers) wherever the value is being used(listened) .
Value can be anything right from being a primitive to a complex data structure
There are two types of signals -
- Writable Signals
- Readonly Signals or Computed Signals
Writable Signals -
Writable signals can be created by using signal()
with some initial value . It can be updated with by using .update()
operation , based on previous value .
We can directly set a new value by using .set()
operation .
Let's look an example where will create a writable signal which will hold some user related information called userInfo
. We will create one more writable signal userAuthenticated
which will store a boolean value whether user is authenticated or not .
Lets see how we can update and read those values from the signals
// creates a writable signal with value as 'true'
userAuthenticated = signal(true);
userInfo = signal({
name : 'Omkar',
loggedIn : true,
permissions : ['READ','UPDATE']
});
showGreetingMessage(){
// in order to read the value from signal
if(this.userAuthenticated()){
console.log(`Welcome to application ${this.userInfo.name}`)
} else {
console.log('Please sign in to get more info')
}
}
updatePermission(newPermission : string){
// updating an existing signal value based on previous value
this.userInfo.update(userValue => {
userValue.permissions.push(newPermission);
return userValue;
});
}
updateAuthetication(value : boolean){
// setting new value to signal directly
this.userAuthenticated.set(value);
}
Computed Signals
Computed signals are readonly signal which generates its value from other signals .
They can be generated by using computed
function provided in @angular/core
package .
In above example where we have created a function to show greeting message based on user authentication , now let's transform that function into a computed signals.
Previously it was written as -
showGreetingMessage(){
// in order to read the value from signal
if(this.userAuthenticated()){
return `Welcome to application ${this.userInfo.name}`
} else {
return 'Please sign in to get more info'
}
}
After converting this function into computed signals , it would look something like this -
showGreetingMessage = computed(() =>
this.userAuthenticated()
? `Welcome to application ${this.userInfo.name}`
: 'Please sign in to get more info'
);
As you can see showGreetingMessage
is a computed signal whose value depends on userAuthenticated
. So whenever userAuthenticated
is updated , angular knows it has to update showGreetingMessage
Can't set values directly to computed signals
You cannot use .set()
method on computed signal to directly set a value for that particular signal . This will result in a compilation error
Computed signals are lazily loaded and memoized
When you read showGreetingMessage
for the first time , only then it calculates its value and cache it . Thereafter whenever you read the signal value again , it returns the cache value .
It updates its cache value only when the signals from which the value is derived is changed . It recalculates itself and returns the updated value
Summary -
Writable Signals
- Store any type of data (numbers, text, objects, arrays)
- Values can be changed directly using
.set()
or.update()
- Automatically notify listeners when values change
Computed Signals
- Get their values from other signals
- Values update automatically when source signals change
- Cannot be modified directly
- Smart performance features:
- Only calculate when first needed (lazy loading)
- Save results for reuse (memoization)
- Recalculate only when source signals change