Ошибка несоответствия типов в rxjs switchMap - PullRequest
0 голосов
/ 06 сентября 2018

Я пытаюсь реализовать typeahead с помощью ng-bootstrap в моем приложении. Я следую примеру википедии , где он выбирает данные с помощью сервиса Wikipedia.

Я реализовал нечто подобное в своем приложении, но у меня проблема несоответствия типов в функции switchMap из rxjs.

Пример из ng-bootstrap:

search = (text$: Observable<string>) =>
  text$.pipe(
    debounceTime(300),
    distinctUntilChanged(),
    tap(() => this.searching = true),
    switchMap(term =>
      this._service.search(term).pipe(
        tap(() => this.searchFailed = false),
        catchError(() => {
          this.searchFailed = true;
          return of([]);
        }))
    ),
    tap(() => this.searching = false)
  )

Моя проблема в том, что когда я пытаюсь реализовать это, term в switchMap представляет собой Observable<{}>, а не string, поэтому я не могу передать его своему сервису.

Как я могу получить действительное значение от наблюдаемого, чтобы передать его на обслуживание?

Моя версия:

search = (text$: Observable<string>) =>
  text$.pipe(
    debounceTime(300),
    distinctUntilChanged(),
    tap(() => this.searching = true),
    switchMap(term =>
      this.placeService.search(term).pipe(  // [ts] Argument of type 'Observable<{}>' is not assignable to parameter of type 'string'. 
        tap(() => this.searchFailed = false),
        catchError(() => {
          this.searchFailed = true;
          return of([]);
        })
    ),
    tap(() => this.searching = false))
  )

Обновление 1

Демонстрация StackBlitz . Если вы посмотрите на app\app.component.ts, вы получите сообщение об ошибке TS.

1 Ответ

0 голосов
/ 06 сентября 2018

После моих комментариев у вас возникла проблема с круглыми скобками. Вот оно, работает .

/*
  Observables are streams that can be monitored. It means that when you 
  subscribe to it, everytime a value is emitted, your subscribe function 
  will be triggered (or in this case, the pipe functions, because you
  subscribe to search() in another component)
*/
search(text$: Observable<string>) {
  return text$
    // pipe = perform operations on the value before sending it to subscribe
    .pipe(
      // debounceTime = wait 300ms before emitting. If a new value is emitted,
      // cancel the previous one
      debounceTime(300),
      // distinctUntilChanged = if the value is the same as the previous one, cancel
      distinctUntilChanged(),
      // tap = perform an operation without touching the value emitted
      tap(() => this.searching = true),
      // switchMap = cancel previous HTTP requests if they're not finished
      switchMap(term => this.placeService.search(term).pipe(
      tap(() => this.searchFailed = false),
      // catchError = self-explanatory :)
      catchError(() => {
        this.searchFailed = true;
        return of([]);
      })
    )),
      tap(() => this.searching = false)
    )
};
...