Offline-resilient fetch
Polling a flaky endpoint the way production apps need to:
- Transient failures retry with exponential backoff.
- Going offline pauses polling entirely.
- Coming back online resumes immediately.
- The last good value stays visible the whole time.
Doing this with useEffect means juggling interval handles, abort flags, retry counters, and online/offline listeners across several pieces of state. As a stream, each requirement is one operator:
- Pause and resume:
online$.pipe(switchMap(...))tears the polling down while offline and rebuilds it on reconnect.timer(0, …)makes the first fetch after reconnect immediate. - Retry with backoff:
retry({count: 3, delay})on the request, with the backoff computed from the attempt number. - Errors don’t kill the poll:
catchErrorsits on the inner request observable. An exhausted retry becomes a status value, and the outer timer keeps ticking. - Keep last-good data: a
scanfolds every status into a view that remembers the most recent successful snapshot.
Try it: hit “Simulate going offline”, wait a few polls, and come back online. The price refreshes immediately. The mock API also fails about a third of the time, so you’ll see the retry path fire on its own.
api.ts is the only mock. It stands in for fromFetch(...) plus, in a real app, an online$ derived from fromEvent(window, 'online') and 'offline' (the wiring is in the comment). The component itself is two useObservable reads.
Last updated on