1
votes

I have three Observables, the first two can be executed at the same time (these not depend on each other), but both responses are needed for the third one. I want to solve this using rxjs / observables and not using promises I found a similar question here but I could not manage to make it work in my project

So far so good, In my agular project I have this:

this.uploadService.uploadPdf(file).subscribe(res =>{
   this.responsePdf = res;
})

if (!!this.thumbnail) {
    this.uploadService.uploadThumbnail(this.file).subscribe(res =>{
        this.responseThumbnail = res;
    })
}

and I need these two responses as params for a third observable, something like:

this.uploadService.submitAll(this.responseThumbnail, this.responsePdf, aString, aNumber).subscribe(res =>{
        // manage response
    })

How can manage this with rxjs and observables without using promises?

2

2 Answers

3
votes

You could use RxJS forkJoin along with the switchMap operator. Try the following

if (!!this.thumbnail) {
  forkJoin({
    pdf: this.uploadService.uploadPdf(file),
    thumbnail: this.uploadService.uploadThumbnail(this.file),
  })
  .pipe(
    switchMap(response => this.uploadService.submitAll(response.thumbnail, response.pdf, aString, aNumber))
  )
  .subscribe(
    response => { // handle reponse },
    error => { // handle error }
  );
}
  1. forkJoin emits the last emitted value when all the observables complete.
  2. switchMap maps to outer observable, completes and emits values from the inner observable.

One big change I see is since we are piping the requests, condition !!this.thumbnail is moved to the outer level and it applies to all the requests. But since you say the 3rd call depends on the output of the 2nd call, it shouldn't change the behavior.

0
votes

You can use chaining observebles accomplish what you need too. Or else you can use forkJoin with the switchMap.

this.uploadService.uploadPdf(file).subscribe(res1 =>{
       this.responsePdf = res1;
        this.uploadService.uploadThumbnail(this.file).subscribe(res2 =>{
             this.responseThumbnail = res2;
                  this.uploadService.submitAll(this.responseThumbnail, this.responsePdf, 
                                aString, aNumber).subscribe(res =>{
                         // manage all your response here
            })
        })
    })