Modern Angular encourages signals — synchronous values for templates and computed. But data often comes from an RxJS service (HTTP, valueChanges). toSignal(observable$) is the bridge: it subscribes to the Observable and holds the last value synchronously.
The problem it solves
Without the bridge you'd subscribe manually in the component, store the value in a field, clean up the subscription on destroy, and separately handle the initial-loading state while the field is still undefined.
Operators and why they matter
toSignal — subscribes IMMEDIATELY on creation. Holds the last value, readable synchronously via signal().
initialValue — what it returns BEFORE the first next. Critically important for loading states.
In the example we simulate the behavior with a toSignalLike function to see the mechanics.
Gotchas
Without initialValue, a synchronous read returns undefined if the Observable didn't emit right away.
Call toSignal ONCE and store the result. Calling it again in a getter or template is a re-subscription → a repeat HTTP request.
For long-lived streams (WebSocket, interval), the signal holds the subscription as long as the injection context lives. Keep that in mind, or you'll leak.
What you get
Async data becomes synchronously readable state with clear initial/loading behavior. The RxJS service and the signal component get along without boilerplate.