Migrating to Angular 15: Signals and Future Reactivity

Date: February 11, 2023


Introduction

Angular 15 brings exciting new reactivity features with Signals, an experimental API that aims to simplify state management and improve performance. Signals offer a fresh approach that could eventually complement or even replace Angular’s long-standing Observable-based reactive model.

In this post, we’ll explore what Signals are, how to start experimenting with them in Angular 15, and how they fit into the future of Angular reactivity.


What Are Signals?

Signals are a new reactive primitive inspired by reactive programming paradigms outside Angular. They represent a piece of reactive state that notifies subscribers automatically when it changes, enabling fine-grained updates without the overhead of full observables.

Think of a Signal as a reactive variable with automatic tracking.


Why Signals?

  • Simpler syntax: Signals are easier to understand and use compared to Observables.
  • Fine-grained reactivity: Components only update when the specific signal they use changes.
  • Improved performance: Reduced overhead by minimizing unnecessary change detection runs.
  • Better integration: Signals can interoperate with existing Angular APIs seamlessly.

Experimental Support in Angular 15

Signals are currently experimental and opt-in in Angular 15. To use them, you need to enable the signals feature flag in your tsconfig.json or enable the experimental zone.


Using Signals: Basic Example

First, import Signals API:

import { signal, computed, effect } from '@angular/core';

Create a reactive signal:

// A signal holding a number value
const count = signal(0);

Update signal value imperatively:

count.set(count() + 1);

Create computed signals derived from other signals:

const doubleCount = computed(() => count() * 2);

React to changes with effect:

effect(() => {
  console.log(`Count changed to: ${count()}`);
});

Using Signals in Angular Components

Here’s a simple counter component using signals:

import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-counter',
  template: `
    <p>Count: {{ count() }}</p>
    <p>Double: {{ doubleCount() }}</p>
    <button (click)="increment()">Increment</button>
  `,
})
export class CounterComponent {
  count = signal(0);
  doubleCount = computed(() => this.count() * 2);

  increment() {
    this.count.set(this.count() + 1);
  }
}

In this example:

  • count is a reactive signal holding the count state.
  • doubleCount automatically recomputes when count changes.
  • The template updates automatically without Angular’s usual change detection cycles.

Signals vs Observables: What’s the Future?

Signals are not intended to immediately replace Observables, but rather to complement Angular’s reactive ecosystem. Observables remain powerful for asynchronous streams like HTTP requests and event handling.

However, Signals provide:

  • Easier state management for synchronous reactive values.
  • Better integration with Angular’s template system.
  • Potential to reduce complexity in many use cases.

How to Start Migrating

  1. Experiment locally: Enable signals in Angular 15 projects and try rewriting small stateful components with Signals.
  2. Gradual adoption: Keep using Observables where they shine, and use Signals for simple reactive states.
  3. Follow Angular updates: Signals will evolve over upcoming releases, so keep an eye on RFCs and Angular blog announcements.

Conclusion

Angular 15’s Signals API marks an exciting evolution in Angular’s reactivity model. By simplifying state management and improving performance, Signals point towards a more intuitive and efficient Angular in the future.

Start experimenting with Signals today to prepare your apps for the next generation of Angular reactivity!

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *