State management is crucial in large-scale Angular applications. Angular 19 introduces Signals, a reactive state management approach that simplifies data flow and enhances performance. This guide explores how to use Signals effectively for managing state in large applications.
ng new angular-signals-app
cd angular-signals-app
Ensure you have Angular 19 installed
ng version
Signals in Angular work like reactive variables that automatically update when their values change.
Example of creating a simple signal:
import { signal } from '@angular/core';
const counter = signal(0);
console.log(counter()); // Output: 0
counter.set(5);
console.log(counter()); // Output: 5
Create a Signal-Based State Management Service
import { Injectable, signal } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class AuthService {
user = signal<string | null>(null);
login(username: string) {
this.user.set(username);
}
logout() {
this.user.set(null);
}
}
Use the Signal in a Component
import { Component, computed } from '@angular/core';
import { AuthService } from '../auth.service';
@Component({
selector: 'app-header',
template: `<p>Welcome, {{ username() }}</p>`,
})
export class HeaderComponent {
username = computed(() => this.authService.user());
constructor(private authService: AuthService) {}
}
computed()
for derived state:import { signal, computed } from '@angular/core';
const price = signal(100);
const quantity = signal(2);
const total = computed(() => price() * quantity());
console.log(total()); // Output: 200
Use effect()
for side effects (like API calls):
import { effect } from '@angular/core';
effect(() => {
console.log('User changed:', authService.user());
});
Example: Managing a Product List
import { Injectable, signal } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class ProductService {
products = signal<Product[]>([]);
addProduct(product: Product) {
this.products.mutate(p => p.push(product));
}
}
Use Products in a Component
import { Component } from '@angular/core';
import { ProductService } from '../product.service';
@Component({
selector: 'app-product-list',
template: `
<ul>
<li *ngFor="let product of products()">{{ product.name }}</li>
</ul>
`,
})
export class ProductListComponent {
products = this.productService.products;
constructor(private productService: ProductService) {}
}
Angular 19 Signals provide an efficient, reactive, and lightweight alternative to traditional state management tools like NgRx. They reduce boilerplate code and improve performance in large-scale applications. By using signals, computed values, and effects, you can build a scalable and maintainable Angular application. 🚀