BACK
Уроки32. UI-фильтры через startWith и combineLatest
Уроки · 32

32. UI-фильтры через startWith и combineLatest

Практика: фильтры списка

Этот урок собирает два прошлых концепта вместе: combineLatest для сборки состояния и startWith для стартовых значений каждого фильтра.

Зачем startWith на каждом источнике

Помните ловушку combineLatest: пока все источники не выдали хотя бы по одному значению, ничего не выходит. Если фильтры созданы лениво (например, из событий ввода), пользователь может долго не трогать поле. Поэтому каждому источнику дают «дефолт» через startWith.

Что произойдёт по шагам

  1. В момент 0мс оба startWith сразу дают значения → выход Filter: /all.
  2. В 20мс query$ сменился на 'rxjs' → выход Filter: rxjs/all.
  3. В 40мс status$ сменился на 'active' → выход Filter: rxjs/active.

Что нужно сделать

  1. К query$ допишите startWith('') в pipe (через запятую после map).
  2. К status$ допишите startWith('all').
  3. Логика combineLatest + map уже готова — менять не нужно.

Детерминированная проверка

В этой задаче проверка идет через виртуальное время TestScheduler. Если решение верное, в консоли появится только Test Passed!. Не добавляйте лишние console.log, иначе проверка провалится.

Решение spoiler · click to reveal
const { timer, combineLatest, map, startWith } = Rx;

const query$ = timer(20).pipe(
  map(() => 'rxjs'),
  startWith('')
);

const status$ = timer(40).pipe(
  map(() => 'active'),
  startWith('all')
);

const filters$ = combineLatest([query$, status$]).pipe(
  map(([query, status]) => 'Filter: ' + query + '/' + status)
);
script.ts // TypeScript
CONSOLE · Console Output
Нажмите на запуск, чтобы увидеть результат...