yudarik
yudarik

Reputation: 113

Promise.all() using RxJs.Observable

I'm trying to implement Promise.all equivalent using RxJs Observable in angular 5, already tried all solutions suggested here, but none of it worked for me, the http requests in the chain simply not fired.

Here's the code I'm trying to execute:

let selected = [{channel: 1},{channel: 2},{channel: 3}];

postToDB(item: any): Observable<any> {
   return this.http.post('/api/items/', item);
}

submitAll() {
   let submitAllSelected = selected.map((item: any) => {
      return this.postToDB(item).map((res: Response) => res.json());
   });

  Observable.forkJoin(submitAllSelected)
    .subscribe((result: any) => {
      this.toaster.success('item saved successfully');
    }, (err: any) => {
      this.toaster.error(JSON.stringify(err));
    }, () => {
     this.toaster.success('All items saved successfully');
    });

}

For some reason, and I not able to figure out, the http request are not fired, after submitAll() is called and the subscribe callback is not called. The only way I did managed to make it work, is when I add .subscribe(cb) or.toPromise() after postToDB() function.

This approach is working well with:

Promise.all(selected.map(item => postToDB(item).toPromise()).then(//do something);

But not with Observable.forkJoin/zip/concat or any other methods I've tried. Will be great if someone can point me where I did wrong.

Upvotes: 1

Views: 1307

Answers (1)

Yerkon
Yerkon

Reputation: 4788

Problem was there:

let submitAllSelected = selected.map((item: any) => {
      return this.postToDB(item).map((res: Response) => res.json());
});

submitAllSelected has type of Observable<Promise<any>>[]. It's should be Observable<any>[]

Correct way:

let submitAllSelected = this.selected.map((item: any) => {
      return this.postToDB(item).pipe(map(data => data))
});

If you use HttpClient no need to convert response to json.

StackBlitz Demo

Upvotes: 1

Related Questions