Brief Note on Signals – Angular 19

Angular 19 introduces an exciting reactive primitive called signals, offering developers a simple yet powerful way to manage local state and derived values without the boilerplate of external libraries. In this blog post, we’ll explore:

  • What signals are in Angular 19
  • A detailed, working example of signals
  • Use cases for signals in real-world apps
  • Differences between signals and NgRx Store

What Are Signals?

A signal is a reactive primitive for storing and tracking state in Angular 19. Under the hood, signals notify subscribers whenever their value changes, enabling automatic updates in templates and computations.

  • Declaration: import from @angular/core
  • 245Functions:
    • signal<T>(initial: T): Creates a writable signal
    • computed<T>(fn: () => T): Derives a signal from other signals
    • effect(fn: () => void): Reacts to changes without returning a value
import { signal, computed, effect } from '@angular/core'; 

// A simple writable signal 
const count = signal(0); 

// A derived signal 
const doubleCount = computed(() => count() * 2); 

// Run an effect when `count` changes 
effect(() => { 
   console.log(`Count changed to ${count()}`); 
});

How It Works:

  1. Read a signal’s value by calling it: count()
  2. Write by invoking its setter: count.set(newValue), or via count.update(x => ...).
  3. Subscriptions: computed and effect track dependencies and re-run when inputs change.

Detailed Working Example: Counter Component

Let’s build a reusable counter using Angular 19 signals.

// counter.component.ts 
import { Component, signal, computed } from '@angular/core'; 

@Component({ 
    selector: 'app-counter', 
    template: ` 
        <div class="counter"> 
        <h2>Counter: {{ count() }}</h2> 
        <button (click)="increment()">Increment</button> 
        <button (click)="decrement()">Decrement</button> 
        <p>Double: {{ double() }}</p> 
        </div> `, 
    styles: [`.counter { text-align: center; } button { margin: 0 8px; }`] 
}) 

export class CounterComponent {
    // 1. Create a writable signal 
    count = signal(0); 

    // 2. Create a derived signal 
    double = computed(() => this.count() * 2); 

   // 3. Methods to update 
   increment() { 
      this.count.update(n => n + 1); 
   } 

   decrement() { 
      this.count.update(n => n - 1); 
   } 
}

Explanation:

  • count holds the current value.
  • double automatically recomputes when count changes.
  • Calling this.count() in template triggers change detection.

Use Cases for Signals

  1. Local Component State: Manage form inputs, toggles, and counters without services.
  2. Derived State: Compute totals, filters, or transforms via computed.
  3. Side Effects: Run business logic when state changes using effect.
  4. Lightweight Stores: Create scoped stores per feature module instead of a global store.

Pro Tip: Combine signals with Angular’s Dependency Injection to provide feature-level state containers.


Signals vs NgRx Store

Feature Signals NgRx Store
Boilerplate Minimal; no actions or reducers Requires actions, reducers, effects, selectors
Scope Local or feature-level Global or large-scale apps
API Surface Signal,computedeffect createEffect, createAction, createReducer, etc.
Learning Curve Low; JavaScript API Higher; Flux architecture
Debug Tools Basic logging via effects Redux DevTools, time-travel debugging
Use Cases Simple, reactive state & derived values Complex state flows, undo-redo, advanced debugging

When to Choose What?

  • Use signals for local state, quick prototypes, and smaller feature modules.
  • Opt for NgRx Store in large enterprise apps needing advanced tooling, middleware, and global consistency.

Conclusion

Angular 19 signals offer a declarative, lightweight, and expressive approach to reactive state in Angular applications. Whether you need simple component state or derived data flows, signals can simplify your code and improve performance. For global, complex state management with robust tooling, NgRx Store remains invaluable—but now you have an elegant, built-in alternative for many scenarios. Please feel free to add comments if any queries or suggestions.

Keep learning & stay safe 😉


You may like:

What’s New in Angular 20

Testing and Debugging Angular 19 Apps

Performance Optimization and Best Practices in Angular 19

If you like our content, please consider buying us a coffee.
Thank you for your support!
Buy Me a Coffee

AngularAngular 19
Comments (0)
Add Comment