Exporting a big report or importing a CSV doesn't finish instantly. The backend returns a jobId, and you poll /jobs/{id} until status becomes done. Then you fetch the file.
The problem it solves
setInterval starts a new poll without waiting for the previous response — on a slow network you get more polls than responses. The interval itself must be cleared manually on destroy, success, and error. It's easy to forget and keep polling after leaving the page.
Operators and why they matter
switchMap — move from startJob to the polling stream.
expand — recursively creates the next poll ONLY after the current one responds. No parallel polls.
takeWhile(status => !done, true) — lets done through (inclusive=true) and ends the polling.
last — the final done-status.
map — return the file from the final response.
Gotchas
interval instead of expand — parallel polls, and the backend gets a flood of requests on a slow network.
repeat without a done condition — infinite polling. The job finished, but you're still polling it.
Forgetting the true on takeWhile — the final done won't pass downstream, last sees nothing, and the stream hangs.
What you get
The polling ends itself on done and returns a single final result. No manual timers or flags.