Run multiple observables sequentially and in order

Viewed 90

I want to chain multiple observables in a single stream and preserve the previous value further down the pipe chain.

Each observable must run sequentially (one after the other, example: if the first observable completes it must go to the next one) and the order is important. I don't want to subscribes to them in parallel (just like forkJoin)

The output must give me the user info, cellphones, addresses and the email of the user.

I can do it with switchmap, this approach does work; but is there a better approach?

Just a dummy example:

    this.userService.getUser(id)
    .pipe(
        switchMap(userResponse => {
            return this.cellphoneService.getCellphones(userResponse.id)
                .pipe(
                    map(cellphonesResponse => [userResponse, cellphonesResponse])
                )
        }),
        switchMap(([userResponse, cellphonesResponse]) => {
            return this.emailService.getEmails(userResponse.id)
                .pipe(
                    map(emailResponse => [userResponse, cellphonesResponse, emailResponse])
                )
        }),
        switchMap(([userResponse, cellphonesResponse, emailResponse]) => {
            return this.addressService.getAddresses(userResponse.id)
                .pipe(
                    map(addressResponse => [userResponse, cellphonesResponse, emailResponse, addressResponse])
                )
        }),
    ).subscribe(response => console.log(response))
1 Answers

Instead of mapping your response to an array after each call, you can instead nest your switchMaps, then all responses will be in scope, so you can just use a single map:

this.userService.getUser(id).pipe(
   switchMap(user => this.cellphoneService.getCellphones(user.id).pipe(
      switchMap(cellphones => this.emailService.getEmails(user.id).pipe(
         switchMap(email => this.addressService.getAddresses(user.id).pipe(
            map(address => [user, cellphones, email, address])
         ))
      ))
   ))
).subscribe(response => console.log(response))

This is described in a little more detail in this answer

Related