Как работать с Observables в rxjs и angular 5, проблема с реализацией начальной загрузки начальной загрузки - PullRequest
0 голосов
/ 23 октября 2018

Я пытаюсь реализовать автозаполнение (начальную загрузку) в angular 5.

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

TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at Object.subscribeToResult (subscribeToResult.js:74)
at SwitchMapSubscriber.push../node_modules/rxjs/operators/switchMap.js.SwitchMapSubscriber._innerSub (switchMap.js:103)
at SwitchMapSubscriber.push../node_modules/rxjs/operators/switchMap.js.SwitchMapSubscriber._next (switchMap.js:96)
at SwitchMapSubscriber.push../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:90)
at DistinctUntilChangedSubscriber.push../node_modules/rxjs/operators/distinctUntilChanged.js.DistinctUntilChangedSubscriber._next (distinctUntilChanged.js:103)
at DistinctUntilChangedSubscriber.push../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:90)
at DebounceTimeSubscriber.push../node_modules/rxjs/operators/debounceTime.js.DebounceTimeSubscriber.debouncedNext (debounceTime.js:98)
at AsyncAction.dispatchNext (debounceTime.js:114)
at AsyncAction.push../node_modules/rxjs/scheduler/AsyncAction.js.AsyncAction._execute (AsyncAction.js:111)
at AsyncAction.push../node_modules/rxjs/scheduler/AsyncAction.js.AsyncAction.execute (AsyncAction.js:86)

и вот мой код:

private searchTerm = new Subject<string>();
public termsArray: any = [];
constructor(private apiService: DataService){
       const result$ = this.searchTerm
       .debounceTime(100)
       .distinctUntilChanged()
       .switchMap(term => this.apiService.getSearchTest(term))
           .subscribe(result => {
                      this.termsArray = result.suggestions as Array<any>;
                      console.log(this.termsArray);
                      }
                      , err => console.log(err))
}

autocompleteTest = (text$: Observable<string>) =>
    text$.pipe(
        debounceTime(300),
        distinctUntilChanged(),
        map(term => term.length < 1 ? []
            : this.termsArray
                .filter(v => v.toLowerCase().indexOf(term.toLowerCase()) > -1)
                .slice(0, 10))
        )

onKeyUpSearch(searchText: string){
    if (searchText !== "") this.searchTerm.next(searchText);
}

1 Ответ

0 голосов
/ 23 октября 2018

Обычно у вас есть две вещи

private searchTerm = new Subject<string>();
observableSearchTerm=this.searchTerm.asObservable()

Вы делаете «следующий» по searchTerm, но подписываетесь на наблюдаемый

onKeyUpSearch(searchText: string){
    if (searchText !== "") this.searchTerm.next(searchText);
}
//But subscribe to the "Observable" 
 this.observableSearchTerm
   .debounceTime(100)
   .distinctUntilChanged()
   .switchMap(term => this.apiService.getSearchTest(term))
       .subscribe(result => {
          ...
   }

ПРИМЕЧАНИЕ 1. В RxJs 6 (Angular 6),Вы должны изменить код, используя pipe

 this.observableSearchTerm.pipe(
   debounceTime(100),
   distinctUntilChanged(),
   switchMap(term => this.apiService.getSearchTest(term))
 ).subscribe(result => {
          ...
 }

ПРИМЕЧАНИЕ 2. Вы можете использовать FromControl и подписаться непосредственно на изменения значений

//In .html
<input type="text" [formControl]="control">

//In .ts
control:FormControl=new FormControl()  //Define the control
//..after in ngOnInit
ngOnInit()
{
   this.control.valueChanges.pipe(
      debounceTime(100),
      distinctUntilChanged(),
      switchMap(term => this.apiService.getSearchTest(term)
   ).subscribe(result=>{
     ....
   })
 }

См. stackblitz

...