
Existing member? Log in and continue learning

See if you like it, start the course for free!

Unlock full course by purchasing a membership
An Introduction to Signals
An Introduction to Signals
Signals are one of the new features in Angular, and it is pretty safe to say they are the new feature.
It might be hard to see why… or even understand what exactly it is they allow us to do.
For example, here is a basic interpolation that we have already covered:
import { Component } from '@angular/core';
@Component({ selector: 'app-home', template: `<p>Hi, {{ name }}</p>`,})export class HomeComponent { name = 'Josh';}
Now here is what it will look like with signals:
import { Component, signal } from '@angular/core';
@Component({ selector: 'app-home', template: `<p>Hi, {{ name() }}</p>`,})export class HomeComponent { name = signal('Josh');}
It’s basically exactly the same… except we have to wrap our Josh
value with
this signal
function that is imported from @angular/core
, and in the
template we also have to use this funny syntax to access the value:
{{ name() }}
When we create our name
:
name = signal('Josh');
It will become whatever this signal
function we are calling returns. The
signal
function will actually return us something called a WritableSignal
which is a type of signal (specifically, one you are allowed to update).
So, basically, the signal function will return us a signal. That means name
is
a signal.
To access the value of a signal
we call it as a function — that is what we are
doing in the template:
{{ name() }}
If we did this instead:
{{ name }}
You would see some nonsense like this in the template:
Hi, function signalFn() { producerAccessed(node); return node.value; }
So it seems that signals do basically the same thing as declaring a class member and using an interpolation, except that it requires extra syntax and comes with some extra confusing nonsense.
Signals and Change Detection
Ok, so given how excited everyone is about these things, it’s safe to say there is some benefit to them.
Perhaps the key thing is how they tie into change detection. This is a topic we are going to cover in a lot more depth in a few lessons time, but what is important to understand for now is that Angular needs to know when something has changed in order to update the view and actually display the change to the user.
For example:
import { Component } from '@angular/core';
@Component({ selector: 'app-home', template: `<p>Hi, {{ name }}</p>`,})export class HomeComponent { name = 'Josh';}
If name
changes from Josh
to Kathy
for any reason, Angular needs to know
so that it can update the DOM appropriately. How does Angular keep track of when
things change? To put it simply, it use a mechanism (Zone.js) that will notify
it when anything possibly could have happened to cause a change. Things that
could potentially cause a change are things like setTimeout
or setInterval
or a promise resolving, or an HTTP request completing, and so on.
Angular gets notified that there could have been a change, and then it checks every component to see if anything needs to be updated.
This isn’t as bad as it sounds — Angular can actually do this quite fast and there are ways to optimise it on the developers end. But, there is certainly room for improvement.
That is where signals come in. It flips this whole problem on its head. Instead of Angular checking whenever anything could have possibly changed, it becomes the role of the signal to tell Angular when it has changed.
If we use signals for our values that change, then it allows Angular to do a lot less change detection work. So, if we do something like this:
name = signal('Josh');
updateName(name: string) { this.name.set(name); }
We are calling set
on our signal which will update its value, but it can also
notify Angular that it has changed. It’s also not just Angular that it will
notify about the change, we can make use of this mechanism as well (more on that
later).
It’s important to note that these change detection changes have not actually been implemented in Angular yet, they will be coming soon in an update. However, as we go through this course we will basically just be pretending that these changes are already in place. Using signals with the current/default change detection strategy will still work anyway, and when the change detection updates do land we will just get all of the benefits for free without needing to change anything.
Basic Signals API
We will be talking about signals a lot in this course. For now, let’s just get a basic understanding of the API.
As we have seen, we can create a signal:
name = signal('Josh');
and access its value as a function:
name()
We can also update a signal’s value with set
:
this.name.set(name);
We can also update a signal’s value with the update
method. The benefit of this
approach is that it gives us a reference to the existing value. This becomes
useful when dealing with objects in a signal. For example:
preferences = signal({ fast: true, comfortable: true, expensive: false, });
toggleComfort() { this.preferences.update((preferences) => ({ ...preferences, comfortable: !preferences.comfortable, })); }
Our signal
now contains an object. In the toggleComfort
method we want flip
the boolean for the comfortable
property. By using the update
method we
spread
the existing preferences
into a new object so that we can keep all of
its existing values, and then we supply a new value for the comfortable
property which will be the opposite of whatever it currently is.
Thanks for checking out the preview of this lesson!
You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).