Skip to content

Common Traps & Misconceptions#

Fast-scan format: the myth interviewers bait with, then the reality. If any correction surprises you, follow the link before the interview.

Myth 1: delay delays errors too

Errors bypass delay entirely and fire immediately, discarding buffered values. Minimum-display-time logic needs separate handling on the error path. → delay

Myth 2: timeout(5000) only limits the first emission

A plain number sets each: it polices every gap between emissions. A long-lived stream that goes quiet mid-life errors too. Use { first: 5000 } for first-only. → timeout

Myth 3: unsubscribe triggers the complete handler

It does not. No notification is delivered on unsubscribe; only teardown and finalize run. Cleanup in complete misses the navigation-away case. → Subscription & Teardown

Myth 4: a notifier that completes stops takeUntil

takeUntil reacts only to an emission. A destroy$ that is completed but never nexted silently stops nothing, which is why the pattern is next() then complete(). → takeUntil

Myth 5: takeUntil works anywhere in the pipe

Operators after it (a switchMap, a shareReplay) can outlive the notification. takeUntil goes last. → Memory Leaks

Myth 6: with refCount: true, shareReplay refetches after everyone unsubscribes

Only while the source is still live. Once it completes (an HTTP response), the value is cached permanently, refCount irrelevant. Refresh requires rebuilding the stream. → shareReplay

Myth 7: BehaviorSubject and ReplaySubject(1) are interchangeable

Three differences: initial value (required vs none), getValue() (yes vs no), and after completion (nothing vs still replays the buffer). Caching flows expose all three. → comparison

Myth 8: multiple async pipes share one subscription

Each | async subscribes independently; on a cold source that means duplicate work and duplicate HTTP requests. Bind once with as, share the stream, or use toSignal. → Async Pipe

Myth 9: of([1, 2, 3]) emits three values

One value: the array. Per-item emission is from([1, 2, 3]). Downstream operators behave completely differently. → of

Myth 10: filter completes the stream when nothing matches

filter never terminates anything; a fully-filtered stream is silent, not complete. Count-based or condition-based completion is take/takeWhile/first. → filter

Myth 11: toObservable emits every signal set()

It runs on effects and coalesces: several synchronous set() calls produce one emission with the final value. Event logs need a Subject. → Signals Interop

Myth 12: combineLatest emits as soon as one source emits

It waits for every source to emit at least once; one silent input blocks all output. Unblock with startWith. → combineLatest

Myth 13: forkJoin emits when its sources have emitted

It waits for completion. A Subject or valueChanges input means it never fires, with no error to warn you. → forkJoin

Myth 14: retrying a from(promise) re-runs the work

The promise already settled; retry just replays the same rejection. Wrap the call in defer(() => from(call())) so each attempt re-executes. → defer

Self-Test#

Cover the explanations and read only the myth lines: correct each one out loud in a sentence. Fourteen for fourteen means this page is done for you; anything less, follow the links.