Signals: computed()

After introducing how to create Signals and how to update them, let’s take a look at one more exciting feature that helps replace the need for RxJs Observables.

How to emit a new Signal value when one or more Signals get updated? That’s what computed() does. In my Signals course, I illustrate computed() with the following example:

In the above code, this.rates() and this.currency() are two different Signals. this.rates() emits up-to-date exchange rates for all currencies in the world. this.currency() emits the current currency selected by the user.

computed() takes a function as a parameter. The function returns the computed value from my two Signals; in this case, the up-to-date exchange rate for the current currency. If the exchange rates or the currency get updated, this computed Signal will emit an updated value automatically.

This is somewhat similar to combining several Observables and using switchMap or combineLatest to get a customized result. It’s a lot easier with Signals (one line of code!).

Two ways to update Angular Signals

Yesterday, I wrote about some best practices around exposing a Signal in our Angular applications. Let’s now take a look at the two different ways a Signal can be updated.

set()

The easiest way to update a Signal is the set() method. Nice and easy for basic data types such as strings or booleans:

update()

When the new value of a Signal depends on its previous value, update() is the best method to use. This is the ideal method for a counter, for instance:

Here is how to increment the counter based on its current value:

TL;DR

  • When you need to update a simple value (string, number, boolean), use set().
  • If that new value is based on the previous one, use update() instead of set()

Signals: Why and when do we need them?

With the release of Angular 16, Signals are now available as a developer preview, which means we can start learning about Signals, testing them, and possibly adopting them.

The end goal of Signals is simple: Improve change detection in the Angular framework by removing the need for Zone.js. A signal-based application will be able to update individual views (a view is a sub-set of a component template — we create new views every time we use structural directives such as ngIf or ngFor) one by one instead of checking the entire component tree, enabling laser-focused updates of our DOM.

A secondary goal is to make Angular easier to learn by making RxJs less critical than before, which also applies to state management libraries such as NgRx or NgXs. In other words, we can rely less on operators, subjects, and the like.

Now that we covered the why, let’s talk about when to use signals. To get the full benefit of Signals in the long run, using them everywhere we have Observables or data bindings makes sense. I know this sounds like a lot of work, but that’s how we can get to a point where Angular can tell exactly which components must be updated when a value changes, no matter their location in the DOM tree.

An upcoming feature of Angular (v17 or later) will be signal-based components, where inputs, outputs, and even two-way bindings will be expressed as Signals:

I believe it makes sense to start using Signals as soon as possible. The base API is available in Angular 16 and is easy to learn. I already published a course that will be continuously updated as Signals evolve.

If you have any specific questions or concerns, feel free to send me your questions. I’ll be covering more about Signals as part of this newsletter.

Angular Signals are in the works!

This is probably the most significant change coming to the framework since the release of Angular v2 many years ago.

A new feature called Signals is being prototyped in Angular, and we can follow the entire discussion on GitHub.

Where do signals come from?

They are the answer from the Angular team to several different requests from the developer community over the years, more specifically:

  • Being able to use Observables with @Input
  • Being able to use Angular without Zone.js to have more control over change detection.
  • Having state management built-in with the framework so we don’t need libraries like NgRx or NgXs anymore.
  • Being able to use Angular in a reactive way without relying on RxJs.

In other words, Signals will be a clear and unified model for how data flows through an application and will work without any dependency (no RxJs, Zone, or other third-party library needed).

Will we have to change everything in our apps?

No, because the Angular team has communicated that:

  • Signals will be optional, and the current way of working with Angular will remain in place.
  • Signals will provide ways to play nicely with RxJs (a Signal can be turned into an Observable and vice-versa)

What will signals look like?

It’s still early to have a definite API. We’re not 100% sure what signals will look like, but the early prototype API looks like this:

Creating a signal with a default value (of 0 in this example)

The above line of code would be very much like doing const counter = new BehaviorSubject(0);

Setting a new value to a signal

Updating a value derived from the current value

Updating a value within a signal (mutation of the internal state)

Displaying the value of a signal in an HTML template or Typescript code

The above would be the equivalent of counter | async when using RxJs. The nice thing is that with Signals, there will be no more .subscribe() and .unsubscribe().

If you want to dive into more details, here is the documentation of the current prototype. Again, this is still early and I would not expect Signals to become fully available before Angular 17 or 18, but this is very exciting nevertheless!