Abdul Ahmad
Abdul Ahmad

Reputation: 10021

rxjs how to pass observable to map

I'm new to angular and rxjs - basically I have a pipe function that takes a few operators, and one of them takes a 'map' with a ternary that is either an empty array or another observable which is a value coming from an http request:

search = (text: Observable<string>) => {
  return text.pipe(
    debounceTime(200),
    distinctUntilChanged(),
    map(term => term.length < 3 ? [] : performSearch(text))
  );
}


performSearch(searchTerm: Observable<string>): Observable<Object> {
  return this.http.get('/api/header-search-results/con').pipe(
    map(res => {
      console.log(res);
      return res;
    })
  );
}

I know I'm doing something wrong, I just don't know what - I'm getting an error in the browser:

Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays

I'd appreciate any guidance

Upvotes: 0

Views: 2486

Answers (2)

madjaoue
madjaoue

Reputation: 5224

with your implementation, merge operator returns either an observable or an object. I suggest you use only objects, or only observables. If you're choosing the second solution, you should also consider an operator that will flatten your stream : concatMap, mergeMap, switchMap, ... according to your needs.

Example of implementation:

search = (text: Observable<string>) => {
  return text.pipe(
    debounceTime(200),
    distinctUntilChanged(),
    concatMap(term => term.length < 3 ? of([]) : performSearch(text))
  );
}


performSearch(searchTerm: Observable<string>): Observable<Object> {
  return this.http.get('/api/header-search-results/con').pipe(
    map(res => {
      console.log(res);
      return res;
    })
  );
}

Upvotes: 1

martin
martin

Reputation: 96891

If you need to return an empty array then just wrap it with of() (in RxJS 6) and then instead of map use mergeMap that will subscribe to the inner Observable returned.

import { of } from 'rxjs';

...

search = (text: Observable<string>) => {
  return text.pipe(
    debounceTime(200),
    distinctUntilChanged(),
    mergeMap(term => term.length < 3 ? of([]) : performSearch(text))
  );
}

Upvotes: 1

Related Questions