简体   繁体   中英

convert rjxs map and flatten/reduce to flatMap

I believe the following code can be refactored using a flatMap but I cant seem to get it working as desired.

I understand flatMap essentially maps and then flattens, which is perfect for me as I'm using forkJoin so get an array of responses back from getAutocompleteSuggestions().

I want a single array of results upon subscription (which is what the code below produces), but changing the top level map to flatMap sends multiple single objects to the subscription. How can this code be better written with flatMap()?

   const $resultsObservable: Observable<any> = Observable.of(query)
          .switchMap(q => this.getAutocompleteSuggestions(q))
          //tried changing the below to flatMap()
          .map(res => { 
            return res.map(resp => {
              const content = resp.content;
              content.map(result => this.someMethod(result));
              return content;
            })
            .reduce((flatArr, subArray) => flatArr.concat(subArray), []);
          });



  getAutocompleteSuggestions(query: string): Observable<any> {
    const subs$ = [];
    //... add some observables to $subs
    return Observable.forkJoin(...subs$);
  }

It looks like there might be a bit of confusion between the RxJS flatMap and the Array prototype method flatMap . Note that the purpose of the RxJS flatMap is not to flatten arrays that are the subjects of the stream, but rather to flatten a stream of Obervables into a single observables. See this SO post:

Why do we need to use flatMap?

... Basically if Observable denotes an observable object which pushes values of type T, then flatMap takes a function of type T' -> Observable as its argument, and returns Observable. map takes a function of type T' -> T and returns Observable.

If you want your code to be a bit cleaner, you could use the myArray.flatMap method. Here's a potential answer to your question with the Array flatMap method:

 const $resultsObservable: Observable<any> = Observable.of(query) .switchMap(q => this.getAutocompleteSuggestions(q)) // Flatmap on the array here because response is an array of arrays. // The RxJS flatMap does not deal with flattening arrays .map(res => res.flatMap(resp => { const content = resp.content; content.map(result => this.someMethod(result)); return content; })); getAutocompleteSuggestions(query: string): Observable < any > { const subs$ = []; //... add some observables to $subs return Observable.forkJoin(...subs$); } 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM