Question presented to candidate:
"Our user-profile page loads data with HttpClient. When the API fails, the page shows nothing and, after one failed lookup, the search box stops working entirely. How does catchError work, how would you show a fallback value, and why might the search box have died?"
What a strong answer should cover:
- An error terminates an Observable: no more values, no completion.
catchErrorintercepts that error and replaces the errored stream with a new Observable you return. - Fallback value:
catchError(() => of(fallback)), which emits the fallback and then completes. Other options:EMPTY(complete silently),throwError(() => mappedError)(rethrow a friendlier error), orcaught(resubscribe, usually better done withretry). - The selector must return an Observable input; returning
undefinedthrows aTypeError, and a plain string is iterated character by character. - Placement:
catchErroron the outer chain swaps the whole stream, so a long-lived trigger (clicks, search terms, actions) dies; put it insideswitchMap/mergeMapon the inner request. - Combine with
retry({ count, delay })before it, and decide whether errors belong in a global interceptor or per call.
Clarifying questions expected:
- "Should the user see a fallback, an error message, or should we retry first?"
- "Is the failing call a one-off load or part of a long-lived stream such as a search box or an effect?"
Code / implementation expected: Yes β a fallback with of() and the inner-vs-outer placement shown on a stream that keeps receiving values.