All files / src/shared/components/AutoComplete useAutoCompleteSearch.ts

100% Statements 23/23
87.5% Branches 7/8
100% Functions 1/1
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 301x 1x       1x 57x   57x 55x 55x 55x 55x 55x 2x 2x 2x 2x 55x 55x 55x   55x 57x   57x 29x 57x 57x  
import { useEffect, useRef } from 'react';
import { Subject, debounceTime, distinctUntilChanged, of, switchMap } from 'rxjs';
 
type FetchFn<T> = (query: string) => Promise<T[]>;
 
export const useAutoCompleteSearch = <T>(query: string, fetchFn: FetchFn<T>, onResults: (res: T[]) => void) => {
  const input$ = useRef(new Subject<string>()).current;
 
  useEffect(() => {
    const sub = input$
      .pipe(
        debounceTime(300),
        distinctUntilChanged(),
        switchMap((searchTerm) => {
          if (!searchTerm || searchTerm.length < 2) return of([]);
          return fetchFn(searchTerm)
            .then((res) => res)
            .catch(() => []);
        })
      )
      .subscribe((results) => onResults(results));
 
    return () => sub.unsubscribe();
  }, [fetchFn]);
 
  useEffect(() => {
    input$.next(query);
  }, [query]);
};