Migrating Observables to Signals in Angular

In this tutorial, you will learn:

  1. What are Signals and Observables
  2. Why need to migrate from Observables to Signals
  3. Step-by-step migration examples
  4. What are the best practices for Angular developers

Introduction

Nowadays, Angular developers use Signals to manage reactive state, while traditionally, developers mostly used RxJS Observables for asynchronous data and state management.

What are Observables in Angular?

Observables come from RxJS, and it is used to handle asynchronous operations like:

  1. API responses
  2. User events
  3. Real-time data

Example using Observable:


import { Observable, of } from 'rxjs';

data$: Observable = of('Hello World!');

To display data in Angular templates:


{{ data$ | async }}

What are Signals in Angular?

Signals are a reactive state management feature that automatically updates the UI when the value changes.

Example:


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

data = signal('Hello World!');

Display data in HTML


{{ data() }}

Observables vs Signals

Feature Observables Signals
Library RxJS Angular Core
Complexity Medium to High Simple
Data type Stream of values Reactive state
Template usage async pipe direct function call
Performance Good Faster change detection

Why need to migrate Observables to Signals?

There are many reasons to migrate from Observables to Signals

1. Simpler State Management

Signals remove the need for complex RxJS operators.

2. Better Performance

Signals are used for better Performance.

3. Cleaner Code

Less boilerplate compared to RxJS subscriptions.

Example: Migrating Observable to Signal

Step 1: Simple Observable Example


import { Component } from '@angular/core';
import { of } from 'rxjs';

@Component({
  selector: 'app-example',
  template: `{{ data$ | async }}`
})
export class ExampleComponent {

  data$ = of('Hello Data');

}

Step 2: Convert Observable to Signal


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

@Component({
  selector: 'app-example',
  template: `{{ data() }}`
})
export class ExampleComponent {

  data = signal('Hello Data');

}

Use Signal into HTTP Observable

Angular HTTP calls return Observables by default.

Simple Example:


this.http.get('/api/users')
  .subscribe(data => {
    this.users = data;
  });

Use Signal in Example


users = signal([]);

this.http.get('/api/users')
  .subscribe(data => {
    this.users.set(data);
  });

Using toSignal() for Migration

Angular has a function toSignal() to convert Observables into Signals.

Example:


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

users = toSignal(this.http.get('/api/users'));

Now you can show users in a template


{{ users() | json }}

When You Should NOT Replace Observables

You should not replace Observable when using below things

1. API calls

2. Event streams

3. Complex async logic

Note: You should use Signal in UI state only.

Common Migration Mistakes

❌ Replacing Observables from API call, Event streams, etc.

❌ Mixing subscriptions and signals incorrectly.

❌ Not using toSignal() helper.

Conclusion

RxJS Observables are used for asynchronous operations, while Angular Signals are ideal for managing UI state.