← Back to Web app developers

Skill · Version 1.0.0

Angular RxJS data flows

Coordinates asynchronous Angular events with deliberate cancellation, sequencing, error recovery and subscription lifetimes.

angular-rxjs

Team members using this skill

See how it helps

When is it useful?

Use when searches race, saves overlap or a failed request prevents later interactions from working.

What does it help you do?

  • Chooses stream operators according to whether work should cancel, queue or overlap.
  • Keeps interactive streams alive after failures with visible loading and retry states.
  • Avoids duplicated HTTP subscriptions and releases subscriptions with their owning component.

Try asking this

Repair live search so old responses cannot win, errors allow another search and leaving the screen cancels its work. Make the first request slow and the second fast. After a network error, another search must still work without creating duplicate subscriptions.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

RxJS & Async Data Flows

Model asynchronous streams declaratively with the flattening, combination and error-handling operators that match the operation's cancellation and ordering semantics.

1. Choosing the right higher-order flattening operator

  • Never nest .subscribe() calls inside another .subscribe(); compose streams with flattening operators based on concurrency and cancellation behavior:
    • switchMap: cancels the previous inner request when a new outer value arrives. Use for reads, typeahead searches, route/filter changes and polling. Never use switchMap blindly on non-idempotent writes whose server completion matters.
    • exhaustMap: ignores new outer emissions while the current inner observable is active. Use for form submissions, login buttons and one-at-a-time triggers to prevent double submit.
    • concatMap: queues inner observables sequentially in order. Use when every write or step must complete in strict order.
    • mergeMap: runs inner observables concurrently. Use only when parallel execution is safe and order does not matter.
  • Remember that cancelling an HTTP observable on the client aborts the browser request but does not roll back work the server has already started.

2. Error handling and stream survival

  • An unhandled error terminates an Observable stream permanently. Inside long-lived streams (such as form valueChanges, action subjects or route param pipelines), place catchError(...) on the inner observable inside switchMap / exhaustMap / concatMap so the outer stream stays alive for subsequent user actions.
  • Expose explicit loading, error and retry states to the UI instead of swallowing errors with catchError(() => EMPTY) silently.

3. Multicasting and avoiding duplicate HTTP requests

  • Cold observables (including HttpClient calls) re-execute per subscriber. When multiple template bindings or derived streams read the same HTTP source, consume it once (via a single @if (data$ | async; as data) / @let, toSignal(), or shareReplay({ bufferSize: 1, refCount: true })).

4. Subscription lifecycle

  • Prefer declarative consumption (async pipe or toSignal()) so Angular manages unsubscription automatically.
  • For imperative subscriptions, always bound their lifetime with takeUntilDestroyed(this.destroyRef), firstValueFrom / take(1) (when completion is guaranteed), or explicit Subscription cleanup in ngOnDestroy.

Before you finish

  • No nested .subscribe() calls; switchMap, exhaustMap, concatMap or mergeMap chosen deliberately.
  • catchError placed on inner streams so user-driven outer streams do not die on the first error.
  • No unintended duplicate HTTP requests from multiple subscriptions to a cold stream.
  • Every long-lived subscription is cleaned up via async pipe, toSignal or takeUntilDestroyed.

Included files 2

  • LICENSE.txt
  • SKILL.md