Angular Signals in depth

Published on 15 January 2024

Understanding Angular's new reactivity model with Signals, Effects and Computed values.

Introduction

Angular 17 introduces Signals as a new reactivity primitive. Unlike RxJS, Signals are synchronous and granular.

Creating a Signal

counter.component.ts
import { signal, computed, effect } from '@angular/core';
const count = signal(0);
const doubled = computed(() => count() * 2);
effect(() => {
console.log(`Count: ${count()}, Doubled: ${doubled()}`);
});
count.set(5); // logs: Count: 5, Doubled: 10

Updating a Signal

counter.component.ts
// Direct replacement
count.set(10);
// Update based on current value
count.update(n => n + 1);

Before / After

// RxJS approach (before)
private count$ = new BehaviorSubject(0);
readonly doubled$ = this.count$.pipe(map(n => n * 2));
this.count$.next(5);
// Signals approach (after)
count = signal(0);
doubled = computed(() => this.count() * 2);
this.count.set(5);

Conclusion

Signals simplify state management code for simple cases and integrate progressively with RxJS via toSignal and toObservable.