Search code examples
rxjsobservableangular9rxjs6switchmap

Angular9/rxjs6.5: How to Transform an Array of Observable Object Array to an Observable Object Property Array?


I'm using Angular(9) Powered Bootstrap (ng-bootstrap 6.1) and am providing ngbTypeahead with an Observable<IKeyValue[]> like so:

search = (text$: Observable<string>) => {
    return text$.pipe(
      debounceTime(200),
      distinctUntilChanged(),
      // switchMap allows returning an observable rather than maps array
      switchMap((searchText) => {
        if (!searchText || searchText.trim().length < 3) {
          // when the user erases the searchText
          return EMPTY;
        } else {
          // get a list of dealer reps
          return this.myService.getKeyValues(searchText);
        }
      })
      , catchError((error) => of(this.myService.postErrorMessage(error)))
    );
  }

I need to transform the output of this.myService.getKeyValues from Observable<IKeyValue[]> to Observable<string[]> by mapping each IKeyValue item to its item.value property.

How do I modify the code above to do that using rxjs 6.5.5?


Solution

  • After the switchMap, you can put a map() operator, do the transformation you need and return the new value.

    It would be something along those lines I think. Note the map in the return value is a different one.

    search = (text$: Observable<string>) => {
    return text$.pipe(
      debounceTime(200),
      distinctUntilChanged(),
      // switchMap allows returning an observable rather than maps array
      switchMap((searchText) => {
        if (!searchText || searchText.trim().length < 3) {
          // when the user erases the searchText
          return EMPTY;
        } else {
          // get a list of dealer reps
          return this.myService.getKeyValues(searchText);
        }
      }),
      map((response: IKeyValue[]) => { //Input parameter is the result from the switchMap
          //I'll do it with a map on the array to retrieve how you want the array by mapping only the property, but you can do in some other way.
          return response.map(item => item.value);
      }),
      catchError((error) => of(this.myService.postErrorMessage(error)))
    );
    

    }