1

I want to send 10 requests that are independent, one after the other in sequence. and want to get all the results in an array. I have tried forkJoin but it hit all the requests in parallel.

For parallel requests

search(queryUrls) {
    queryUrls.forEach((query) => {
        observableBatch.push(this.http.post(query.url, query.data))
            .pipe(
                map((res) => res),
                catchError(e => of('Error'))
            );
    });

    //
    return forkJoin(observableBatch);
}

and I can subscribe this method and can get all the results in an array. but how can I send all the requests in sequence?

Srdjan Pazin
  • 103
  • 2
  • 5
Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
  • Possible duplicate of [How to chain Http calls in Angular2?](https://stackoverflow.com/questions/34104638/how-to-chain-http-calls-in-angular2) – Igor Apr 07 '19 at 11:26

2 Answers2

0

You need to use concat instead.

concat will subscribe to first input Observable and emit all its values, without changing or affecting them in any way. When that Observable completes, it will subscribe to then next Observable passed and, again, emit its values. This will be repeated, until the operator runs out of Observables. When last input Observable completes, concat will complete as well.

If you then want to gather all those results into an array you will need to use the toArray operator to collapse the results.

In your case it will look something like:

const batched = queryUrls.map(query => this.http.post(query.url, query.data))
concat(batched).pipe(toArray()).subscribe(allResults => /**/)
paulpdaniels
  • 18,395
  • 2
  • 51
  • 55
  • on subscribe it is returning `[Observable, Observable]` – Sunil Garg Apr 07 '19 at 11:35
  • 1
    @SunilGarg `concat` (and `merge`) don't subscribe to the Observables with an array of Observables as input. You have to use the spread operator `concat(...batched)`. – frido Apr 08 '19 at 08:05
0

Solution (concatMap keeps the order of the requests)

   const results = [];
   search(queryUrls) {
       from(queryUrls).pipe(
         concatMap((query) => this.http.post(query.url, query.data)),
         catchError(e => of('Error'))
       ).subscribe((response) => results.push(response.body));
    }

Explanation: Difference between mergeMap, switchMap and concatMap

if you want to send the results in another observable when all the requests are done, you can do so this way

output$ = new Subject();
   search(queryUrls) {
       const results = [];
       from(queryUrls).pipe(
         concatMap((query) => this.http.post(query.url, query.data)),
         catchError(e => of('Error'))
       ).subscribe(
         (response) => results.push(response.body),
         () => {},
         () => { output$.next(results); } // this is executed on complete
       );
    }
Meddah Abdallah
  • 654
  • 1
  • 7
  • 25