Lars
Lars

Reputation: 1092

How to perform multiple HTTP requests from an array using RXJS?

Currently, I'm developing a sync service with Angular. Here I'm doing a database request and get back an array of URLs. Now I want to process each URL in sequence. Here is my code so far:

    return this.http.get<any[]>(url + '/recovery').pipe(
        map((response: any) => {

            return from(response).pipe(
                concatMap((item: any) => {

                    switch (item.method) {
                        case 'POST':
                            return this.post(item.url, item.data);
                        case 'PUT':
                            return this.update(item.url, item.data);
                        case 'DELETE':
                            return this.delete(item.url);
                    }
                })
            );
        })

The returned array of the initial HTTP request looks something like this:

[
    {method: 'POST', url: 'xxx.com/aaa', data: {...}},
    {method: 'POST', url: 'xxx.com/bbb', data: {...}},
    {method: 'PUT', url: 'xxx.com/ccc'},
]

In the next step I do a subscription like:

this.restService.syncRecovery().subscribe(response => {
    console.log('SYNC DONE', response);
});

The subscription works, but the "inner" http requests (concatMap) wont be processed. I expect that this will be a simple problem, but I can't find it and hope that somebody here can give some support, please.

Thx!

Upvotes: 0

Views: 662

Answers (1)

Barremian
Barremian

Reputation: 31105

Everything looks fine except you need to use switchMap instead of map as the parent mapping operator.

return this.http.get <any[]> (url + '/recovery').pipe(
  switchMap((response: any) => {            // <-- `switchMap` here
    return from(response).pipe(
      concatMap((item: any) => {
        switch (item.method) {
          case 'POST':
            return this.post(item.url, item.data);
          case 'PUT':
            return this.update(item.url, item.data);
          case 'DELETE':
            return this.delete(item.url);
        }
      })
    );
  })
);

And I assume this.post, this.update, and this.delete are wrappers for HTTP requests.

Upvotes: 1

Related Questions