0

I am trying to create an autocomplete that receive data from an API for each typing, now i have the displayed each time but first i am always having this error for each type .

You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

even when i subscribe the data into a variables , nothing happens. this the immage of the error, and you will see the displayed dataenter image description here

this this my app.component.ts

ngOnInit() {
    this.results = this.searchText.valueChanges.pipe(
      startWith(''),
      // delay emits
      debounceTime(300),
      switchMap(value => {
        if (value !== '' && value !== undefined) {
           this.lookup(value).subscribe((value: any) => {
             console.log('data sub:', value);
           });
        } else {
          return of(null);
        }
      })
    );
  } 

lookup(value: string): Observable<any> {
    return this.appService.autoComplete(value.toLowerCase()).pipe(
      map(results => results.hits.hits)
    );
  }

and this is my service.ts

  public autoComplete(name: string): Observable<Response> {


    const params = new HttpParams()
        .set('name', name);
    return this.httpClient.get<Response>(this.host, { params});
}

also this is my html aswell:

 <input type="text" matInput   [matAutocomplete]="auto"
                [formControl]="searchText" >
                <mat-autocomplete #auto="matAutocomplete" >
                  <mat-option *ngFor="let item of results | async " [value]="item._source.firstname">
                    {{item._source.firstname}}
                  </mat-option>
                </mat-autocomplete>

1 Answers1

5

You shouldn't subscribe inside the switchMap operator. It is meant to switch from one observable to another. So it should essentially return the observable and the subscription must be at the end of the operators chain. In your case, the subscription is done by the async pipe in the template.

ngOnInit() {
  this.results = this.searchText.valueChanges.pipe(
    startWith(''),
    debounceTime(300),    // delay emits
    switchMap(value => {
      if (value !== '' && value !== undefined) {
        return this.lookup(value);      // <-- return `this.lookup()` here
      } else {
        return of(null);
      }
    })
  );
}

Additional QoL changes:

  1. Use double-bang operator !! to check variable validity. Empty string '' is falsy.
  2. Use RxJS iif to conditionally return an observable.
  3. Use RxJS NEVER constant instead of of(null).
ngOnInit() {
  this.results = this.searchText.valueChanges.pipe(
    startWith(''),
    debounceTime(300),    // delay emits
    switchMap(value =>
      iif(
        () => !!value,
        this.lookup(value),
        NEVER
      )
    )
  );
}
ruth
  • 29,535
  • 4
  • 30
  • 57