1
votes

I have a list of user IDs and I want to make an HTTP request for each user and then return results from the server as a single array using RxJS.

Observable
  .from([1020, 3050, 4400, 1720])
  .mergeMap((userId: number) => {
    return httpGet('/users/' + userId);
  })
  .map((response: Response) => {
    return response.json();
  })
  .subscribe((user: any) => {
    console.log('User:', user);
  })
;

Using the code above I now receive each user as a separate emission, however, I would like to receive a single array in the end:

.subscribe((users: any[]) => {
  console.log('Users:', users);
});

How do I group all emissions from RxJS observable in a single array result?

2

2 Answers

2
votes

After struggling with this problem for some time, I've decided to publish here a solution in order to make it easier to find. I hope it will help someone.


You can use the toArray() operator for this. It will collect all the emissions until the source completes and then will re-emit them as a single array.

So, the working example will look like this:

Observable.from([1020, 3050, 4400, 1720])
  .pipe(
    mergeMap(userId => httpGet(`/users/${userId}`)),
    map(response => response.json()),
    toArray(),
  )
  .subscribe(users => console.log('Users:', users));
;
0
votes

Since rxjs 6, the syntax needs to be adapted with .pipe(), otherwise yes, toArray works.

import { interval } from 'rxjs';
import { take, toArray } from 'rxjs/operators';

interval(100)
  .pipe(take(10), toArray())
  .subscribe(console.log);