1

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.

yudarik
  • 113
  • 1
  • 12

1 Answers1

1

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

Yerkon
  • 4,548
  • 1
  • 18
  • 30
  • Ohhh wow! This actually worked! But I've suddenly discovered why it did not worked for me all the way... Appears, that the function I've used: `postToDB(item: any)` used a proxy function that was type-less, meaning that it did not returned Observable, but typed as void instead. Strange, since typing should not change the returned value anytime. – yudarik Apr 26 '18 at 11:40