Angular Signals: The Future of Reactivity

What Are Signals?

Signals are a new reactive primitive in Angular that provide fine-grained reactivity. Unlike observables, signals are synchronous and automatically track dependencies.

Basic Signal Usage

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

@Component({
  selector: 'app-counter',
  template: `
    

Count: {{ count() }}

Double: {{ doubleCount() }}

` }) export class CounterComponent { // Create a writable signal count = signal(0); // Create a computed signal (read-only, derived value) doubleCount = computed(() => this.count() * 2); increment() { // Update signal value this.count.update(value => value + 1); // Or set directly: this.count.set(10); } }

Effects

Effects run side effects when signals change:

@Component({...})
export class UserComponent {
  userId = signal(null);
  user = signal(null);
  
  constructor() {
    // Effect runs when userId changes
    effect(async () => {
      const id = this.userId();
      if (id) {
        const userData = await this.userService.getUser(id);
        this.user.set(userData);
      }
    });
  }
}

Signal-Based Inputs

@Component({
  selector: 'app-user-card',
  template: `
    

{{ fullName() }}

{{ user().email }}

` }) export class UserCardComponent { // Signal-based input user = input.required(); // Computed from input fullName = computed(() => `${this.user().firstName} ${this.user().lastName}` ); }

Signal-Based Outputs

@Component({
  selector: 'app-search',
  template: `
    
  `
})
export class SearchComponent {
  query = signal('');
  
  // Output using outputFromObservable or output()
  searchChange = output();
  
  onInput(event: Event) {
    const value = (event.target as HTMLInputElement).value;
    this.query.set(value);
    this.searchChange.emit(value);
  }
}

State Management with Signals

// Simple store using signals
@Injectable({ providedIn: 'root' })
export class CartStore {
  private items = signal([]);
  
  // Public read-only access
  readonly cartItems = this.items.asReadonly();
  
  readonly totalItems = computed(() => 
    this.items().reduce((sum, item) => sum + item.quantity, 0)
  );
  
  readonly totalPrice = computed(() =>
    this.items().reduce((sum, item) => sum + item.price * item.quantity, 0)
  );
  
  addItem(product: Product) {
    this.items.update(items => {
      const existing = items.find(i => i.productId === product.id);
      if (existing) {
        return items.map(i => 
          i.productId === product.id 
            ? { ...i, quantity: i.quantity + 1 }
            : i
        );
      }
      return [...items, { productId: product.id, quantity: 1, price: product.price }];
    });
  }
  
  removeItem(productId: string) {
    this.items.update(items => items.filter(i => i.productId !== productId));
  }
}

Converting from RxJS

import { toSignal, toObservable } from '@angular/core/rxjs-interop';

@Component({...})
export class DataComponent {
  private http = inject(HttpClient);
  
  // Convert Observable to Signal
  users = toSignal(
    this.http.get('/api/users'),
    { initialValue: [] }
  );
  
  selectedId = signal(null);
  
  // Convert Signal to Observable
  selectedId$ = toObservable(this.selectedId);
}

Performance Benefits

  • Fine-grained updates - only affected components re-render
  • No zone.js dependency with zoneless change detection
  • Synchronous reads - no async complexity
  • Automatic dependency tracking

Best Practices

  • Use signals for component state
  • Use computed for derived values
  • Use effects sparingly for side effects
  • Keep signals close to where they're used
  • Consider signal-based stores for shared state

Conclusion

Signals represent Angular's evolution toward simpler, more performant reactivity. Start using them in new components and gradually migrate existing code.

๐Ÿ“šTechnical Insights & Industry Trends

Insights & Knowledge Hub

Explore in-depth articles on software development, digital transformation, and emerging technologies. Learn from real-world experience.

Browse by Topic

๐Ÿ…ฐ๏ธ
ArchitectureJan 2024

Why Angular SSR Beats React for SEO in 2024

A comprehensive comparison of server-side rendering implementations and their impact on search engine optimization, performance, and user experience.

๐Ÿ”Œ
ArchitectureDec 2023

Microservices: When to Use and When to Avoid

Understanding the trade-offs of microservices architecture and making the right choice for your organization's scale, complexity, and team structure.

๐Ÿ—๏ธ
System ArchitectureJan 2024

Essential Design Patterns for Enterprise Systems

Master the fundamental design patterns that every software architect should know for building scalable, maintainable enterprise applications.

๐Ÿ—๏ธ
System ArchitectureJan 2024

Domain-Driven Design: A Practical Guide

Learn how to apply Domain-Driven Design principles to create software that truly reflects business requirements and scales with organizational complexity.

๐Ÿ—๏ธ
System ArchitectureDec 2023

Event-Driven Architecture: Complete Implementation Guide

Build loosely coupled, scalable systems using event-driven architecture patterns with practical examples using Kafka, RabbitMQ, and Azure Service Bus.

๐Ÿ—๏ธ
System ArchitectureDec 2023

RESTful API Design: Best Practices and Patterns

Design APIs that developers love to use. Learn REST principles, versioning strategies, error handling, and documentation best practices.

Deep Dives into Key Areas

๐Ÿ—๏ธ

System Architecture

Design patterns and architectural decisions

12 Articles
โ˜๏ธ

Cloud Computing

AWS, Azure, and cloud-native development

8 Articles
โšก

Performance

Optimization and scalability techniques

6 Articles
๐Ÿค–

AI & Machine Learning

Practical AI applications in enterprise

5 Articles
๐Ÿ”’

Security

Best practices and compliance

7 Articles
๐Ÿ“ฑ

Modern Frontend

Angular, React, and UI/UX best practices

10 Articles

Have a Project in Mind?

Let's turn your ideas into reality. Schedule a free consultation to discuss how we can help transform your business.