home / skills / hoangnguyen0403 / agent-skills-standard / rxjs-interop
This skill helps you bridge RxJS observables and signals using toSignal and toObservable for seamless template rendering and reactive logic.
npx playbooks add skill hoangnguyen0403/agent-skills-standard --skill rxjs-interopReview the files below or copy the command above to add this skill to your agents.
---
name: RxJS Interop
description: Bridging Observables and Signals using toSignal and toObservable.
metadata:
labels: [angular, rxjs, signals, interop]
triggers:
files: ['**/*.ts']
keywords: [toSignal, toObservable, takeUntilDestroyed, rxjs angular]
---
# RxJS Interop
## **Priority: P1 (HIGH)**
## Principles
- **Async to Sync**: Use `toSignal` to convert Observables (HTTP, Events) to Signals for template rendering.
- **Sync to Async**: Use `toObservable` when you need RxJS operators (debounce, switchMap) on a Signal.
- **Auto-Unsubscribe**: `toSignal` automatically unsubscribes.
- **Cleanup**: Use `takeUntilDestroyed` for manual subscriptions in injection contexts.
## Guidelines
- **HTTP Requests**:
- GET: `http.get().pipe(...)` -> `toSignal()`
- POST/PUT: Trigger explicit subscribe() or lastValueFrom().
- **Race Conditions**: Handle async loading states. `toSignal` requires an `initialValue` or handles `undefined`.
## References
- [Signals vs Observables](references/observables-vs-signals.md)
This skill documents practical patterns for bridging RxJS Observables and Angular Signals using toSignal and toObservable. It provides concise rules for when to convert streams to signals, when to treat signals as observables, and how to avoid common pitfalls like leaks and race conditions. The guidance targets HTTP, event streams, and injection-context subscriptions in TypeScript Angular apps.
toSignal converts an Observable into a Signal suitable for template rendering and automatically unsubscribes when the consuming component is destroyed. toObservable converts a Signal into an Observable to enable RxJS operators such as debounceTime, switchMap, and combineLatest. For manual subscriptions inside services or constructors, use takeUntilDestroyed to ensure proper cleanup.
Do I always need to pass an initialValue to toSignal?
Not always, but passing an initialValue avoids undefined in templates and reduces race-condition risks. If you expect delayed emissions, provide a sensible default and manage loading state.
When should I use toObservable instead of directly using Signals?
Use toObservable when you need RxJS operators (debounceTime, switchMap, combineLatest) or when interacting with existing Observable-based APIs. For straightforward UI binding, Signals are simpler and preferred.