How to Replace BehaviorSubject with signal() in Angular



This content originally appeared on DEV Community and was authored by Chandan Kumar

Angular 17+ introduced a new way to handle reactive state using signals, which can be simpler than using RxJS BehaviorSubject in many cases. Let’s learn how to switch from BehaviorSubject to signals.

Introduction:

Are you using BehaviorSubject in Angular to manage your app’s state? It works well, but now there’s a better and easier way with Angular 17+ it’s called signal().

In this blog, you’ll learn how to replace BehaviorSubject with signal() using a simple example. Let’s make Angular development easier!

Why Change from BehaviorSubject to Signals?

BehaviorSubject works well but has some drawbacks:

Requires .next() to update values
Needs manual subscription management
Can lead to complex code

Signals are better because:
✔ Easier to use
✔ No manual subscriptions/unsubscriptions
✔ Better performance
✔ Works perfectly with Angular templates

Before: Using BehaviorSubject

Here’s how you might use BehaviorSubject in a service:

@Injectable({ providedIn: 'root' })
export class UserService {
  private userSubject = new BehaviorSubject<User | null>(null);
  user$ = this.userSubject.asObservable();

  setUser(user: User) {
    this.userSubject.next(user);
  }

  clearUser() {
    this.userSubject.next(null);
  }
}

And in the component:

export class ProfileComponent implements OnInit {
  user: User | null = null;

  constructor(private userService: UserService) {}

  ngOnInit() {
    this.userService.user$.subscribe(user => {
      this.user = user;
    });
  }
}

After: Using signal()Angular’s new signal() function makes the same logic much simpler:

Updated Service

import { Injectable, signal } from '@angular/core';
import { User } from './user.model';

@Injectable({ providedIn: 'root' })
export class UserService {
  private user = signal<User | null>(null);

  getUser = this.user.asReadonly();// Makes signal read-only

  setUser(user: User) {
    this.user.set(user);// Updates value
  }

  clearUser() {
    this.user.set(null);
  }
}

Updated Component

export class ProfileComponent {
  user = this.userService.getUser();// Automatically reactive!

  constructor(private userService: UserService) {}
}

Now you don’t need manual subscriptions or ngOnInit!

Just like that, you’ve eliminated the need for manual subscription/unsubscription and made the state reactive by default!

Benefits of Switching to signal()

| Feature               | BehaviorSubject           | signal()              |
| --------------------- | ------------------------- | --------------------- |
| Boilerplate           | High                      | Low                   |
| Subscriptions         | Required                  | Not Required          |
| Memory Leaks Risk     | Yes (without unsubscribe) | No                    |
| Type-Safe Access      | Not always                | Always                |
| Integration with View | Manual                    | Seamless in templates |

Using Signals in Templates

You can directly use signals in templates:

<div *ngIf="user(); else guest">
  Welcome, {{ user().name }}!
</div>
<ng-template #guest>
  Please log in.
</ng-template>

Notice user() – this is how you read a signal’s value.

When to Use Signals

  • Simple state management (auth status, loading flags)
  • UI state (theme, sidebar toggle)
  • Derived values (using computed())

Migration Tips

  • Use signal() for simple reactive values.
  • Use computed() for derived states.
  • Avoid combining signals with observables unless necessary.
  • Replace .next() with .set() or .update().

Conclusion

Signals make Angular state management simpler and more efficient. While RxJS is still useful for complex async operations, signals are great for most reactive state needs.

Start by converting one service to signals and see the difference!

Stay Updated

Follow me for more design tips and tools! ✨

🐙 GitHub: Follow me for more web development resources.
🔗 LinkedIn: Connect with me for tips and tricks in coding.
✍ Medium: Follow me for in-depth articles on web development.
📬 Substack: Dive into my newsletter for exclusive insights and updates:
🌐 Bento — Explore all my work in one place.
🧭 Linktree — Access my resources, blogs, and social links easily


This content originally appeared on DEV Community and was authored by Chandan Kumar