Lessons56. Final exam: a liveSearch operator
Lessons · 56
56. Final exam: a liveSearch operator
Final exam — a production-grade liveSearch
Congratulations — this is the course's last lesson. Here we bring it all together: operators to control the stream, error handling, retries, a fallback. The result is an operator that's genuinely ready for production.
The full chain
function liveSearch(searchApi) {
return source$ => source$.pipe(
debounceTime(20), // wait for a pause in typing
distinctUntilChanged(), // drop repeats
switchMap(query =>
searchApi(query).pipe( // the inner request
retry(1), // one retry
catchError(() => of('Fallback: ' + query)) // the last line of defense
)
)
);
}
Why exactly this
retryandcatchErrorsit insideswitchMap— this is critical. Move them outside and one request's error kills the whole search stream forever.retry(1)— one retry for random network hiccups.catchError— the final safety net: if the retry didn't help, return a safe string.
Your task
- In the
liveSearchfunction, fill insource$.pipe(...)— see the full chain above. - The marble test: query
ris cancelled by the debounce,rxreturnsResult: rxsuccessfully,badfails, retry tries once more — it fails again — and catchError returnsFallback: bad. - The check confirms
badcaused exactly2attempts.
Deterministic check
This task's check runs in TestScheduler virtual time. If your solution is right, the console shows only Test Passed!. Don't add extra console.logs, or the check will fail.
Solution spoiler · click to reveal
const { of, defer, debounceTime, distinctUntilChanged, switchMap, retry, catchError } = Rx;
function liveSearch(searchApi) {
return source$ => source$.pipe(
debounceTime(20),
distinctUntilChanged(),
switchMap(query => {
return searchApi(query).pipe(
retry(1),
catchError(() => of('Fallback: ' + query))
);
})
);
} script.ts
CONSOLE · Console output
Hit Run to see the result...