How to start observable in the pipe in RxJS 6?

Viewed 1023

I have this RxJS code in my Angular project:

settingsService.getSetting('setting-name').pipe(
  map((setting: SettingInterface) => {
    // ...

    return setting;
  }),
  tap((setting: SettingInterface) => this.settingService.save(setting)),
  map((setting: SettingInterface) => {
    // ...
  })
);

In this code the this.settingService.save(setting) is an Observable too, and it isn't subscribed.

How can I start this observable in the pipe, wait for it and continue?

Important:

  • the save() observable must start after prevoius map() operator
  • the result of the save() observable is irrelevant in the pipe and I want to drop it
  • the save() observable must start before next map() operator

Is there any RxJS operator to do this?

1 Answers

When you have an observable that depends on another observable, you could use one of the RxJS's higher order mapping operator like switchMap, concatMap, flatMap or exhaustMap. Each has their own purpose. Here's a good rundown. Essentially, upon subscription they convert one observable to another and return the modified observable.

I'll use switchMap to illustrate.

settingsService.getSetting('setting-name').pipe(
  map((setting: SettingInterface) => {
    // ...

    return setting;
  }),
  switchMap((setting: SettingInterface) => 
    this.settingService.save(setting).pipe(map(_ => setting))
  ),
  map((setting: SettingInterface) => {
    // ...
  })
);

You'll notice I've piped in another map to the inner obesrvable: .pipe(map(saved => setting)). Without this the following outer map would receive the output from this.settingService.save(setting) instead of the setting variable that you require.

Related