---
title: "RxJS and signal interoperability"
chapter: "09"
---

# RxJS and signal interoperability

RxJS models asynchronous streams with time, cancellation, and operators.
Signals model current synchronous state. Angular applications often need both.

## Flattening operators

- `switchMap`: cancel obsolete work; good for search;
- `concatMap`: queue in order; good for serialized commands;
- `exhaustMap`: ignore new triggers while busy; useful for submit protection;
- `mergeMap`: run concurrently; bound concurrency when needed.

The operator encodes product behavior. Choose it deliberately.

## Ownership

Prefer AsyncPipe, `toSignal`, or `takeUntilDestroyed` to bind subscription
lifetime to Angular ownership. Nested subscriptions hide cancellation and error
flow.

## Subjects

Subjects are both producer and consumer. Use them for actual event bridges, not
as mutable global state by default. BehaviorSubject offers a current value but
can spread imperative writes.

## Errors

An Observable normally terminates on error. Place `catchError` at the boundary
whose fallback is valid. Returning an empty stream can silently remove critical
data.

## Sharing

`shareReplay` can cache and share, but its buffer, reference-count, completion,
and stale/error behavior must be understood. It is not an application cache
strategy by itself.

## Interop strategy

Keep server event streams, websockets, and complex async workflows in RxJS.
Expose stable current UI state as signals. Avoid converting back and forth at
every method.

## Feynman check

A signal answers “what is the value now?” An Observable answers “what values
arrive over time?” Explain why a search result page may use both.
