Question presented to candidate:
"In this template we use user$ | async in three places and someone says that is fine because the async pipe handles everything. Explain what the async pipe actually does, why it is useful, and whether that template is fine."
What a strong answer should cover:
| asyncsubscribes to an Observable (or waits on a Promise), returns the latest value (nullbefore the first one), and callsmarkForCheck()on each new value, so it works with OnPush and zoneless apps.- It unsubscribes automatically when the view is destroyed, and when the expression starts returning a different Observable instance.
- Each
| asyncis its own subscription: three pipes on a cold HTTP Observable are three requests. Use one@if (user$ | async; as user)block,shareReplay, ortoSignal(). - Never pipe a method or getter that creates a new Observable on every evaluation: it re-subscribes forever and never shows a value.
- Errors from the stream go to the app
ErrorHandler; handle them withcatchErrorin the pipeline. The pipe does not unwrap signals. - In Angular 22,
toSignal()is the signal-first alternative; the async pipe remains fully supported.
Clarifying questions expected:
- "Is
user$an HTTP call or a shared store stream?" - "Is this component signal-based already, or still Observable-based?"
Code / implementation expected: Yes — one async-pipe subscription with @if ... as, a live stream showing unsubscribe on destroy, and a Promise.