#rxjs #tutorial #advanced

Day 10: Real-world Recipe (Typeahead Search)

Day 10: The Ultimate Search Component

Congratulations! You’ve learned the individual lego bricks of RxJS. Now, let’s build something real.

We will build a Typeahead Search that:

  1. Waits for the user to stop typing (Debounce)
  2. Ignores duplicates (Distinct)
  3. Cancels old requests (SwitchMap)
  4. Handles errors gracefully (CatchError)

The Code

import { fromEvent, of } from 'rxjs';
import { 
  map, 
  filter, 
  debounceTime, 
  distinctUntilChanged, 
  switchMap, 
  catchError 
} from 'rxjs/operators';

// Simulated API Call
function searchApi(term) {
  console.log(`Searching API for: ${term}`);
  if (term === 'error') {
    throw new Error('Server limit!');
  }
  return of([`Result A for ${term}`, `Result B for ${term}`]);
}

const input = document.getElementById('search-box');

const search$ = fromEvent(input, 'keyup').pipe(
  // 1. Get value
  map((e: any) => e.target.value),

  // 2. Ensure length > 2
  filter(text => text.length > 2),

  // 3. Wait 300ms for pause
  debounceTime(300),

  // 4. Only if changed
  distinctUntilChanged(),

  // 5. Cancel previous request!
  switchMap(term => {
    return searchApi(term).pipe(
      // 6. Handle inner errors locally (so stream stays alive)
      catchError(err => of([])) 
    );
  })
);

search$.subscribe(results => {
  console.log('Update UI with:', results);
});

Why is this “Clean Architecture”?

  • Declarative: You can read the logic top-to-bottom.
  • Resilient: It handles race conditions (switchMap) and errors automatically.
  • Efficient: It minimizes server load (debounce, distinct).

Conclusion

You have graduated from the RxJS Reactive Masterclass!

Recap:

  • Observables are streams of data.
  • Operators transform that data.
  • Subscriptions activate the stream.

Next Steps:

  • Try implementing this in Angular (which uses RxJS natively).
  • Explore state management libraries like NgRx or Akita.

Thank you for coding along. Keep streaming!