Reputation: 961
I have an RXJS Pipeline similar to this:
const logs: number[] = [1, 2, 3, 4];
const url = 'http://some-url-here.com';
const pipeline = from(logs).pipe(
switchMap(logId =>
this.callEndpoint(url, logId).pipe(map(response => response.data)),
),
);
const res = await pipeline.toPromise();
console.log(res);
// The real function uses nestJS http service to call a url
callEndpoint(url: string, logId: number) {
const result = Math.random() * 1000;
console.log(`result in callEndpoint: ${result}`);
return of({ data: result });
}
here is a sample output of the code:
result in callEndpoint: 586.773956063481
result in callEndpoint: 842.136341622411
result in callEndpoint: 964.0849490798163
result in callEndpoint: 598.7596176858414
598.7596176858414
The last number is the result of res
.
How do I get the combined results of all the successful endpoint calls into a single array in res
?
Upvotes: 0
Views: 727
Reputation: 14129
Use forkJoin
if you want to send all requests at once or concat
with toArray
to send requests sequentially and collect the results in an array. You probably want to add error handling with catchError
and return an observable that doesn't error in this case.
const getData = (logId) => this.callEndpoint(url, logId).pipe(
map(response => response.data),
catchError(error => of(null))
)
const requests = logs.map(logId => getData(logId));
// parallel requests
forkJoin(requests).subscribe(res => console.log(res));
// sequential requests
concat(...requests).pipe(toArray()).subscribe(res => console.log(res));
res
will be an array that can contain null
values if a request failed.
When the second request fails this might look like:
[586.773956063481, null, 964.0849490798163, 598.7596176858414]
Upvotes: 2
Reputation: 96949
You can use toArray()
to collect all emission and emit them as one array after the source observable completes.
const pipeline = from(logs).pipe(
switchMap(logId =>
this.callEndpoint(url, logId).pipe(map(response => response.data)),
),
toArray(),
);
However, I think you don't want to be using switchMap
in this case because the source observable here is from()
that will emit all items from logs
immediatelly and switchMap
will keep subscribed only to the last one. So you might want to use concatMap
instead.
Upvotes: 1