rxjs condition inside flatmap

主宰稳场 提交于 2019-12-11 02:49:43

问题


I want to have a condition inside flatMap that checks what was returned by first observable. If condition is not met I would like to break and navigate to different page.

this.service.getData(id)
  .flatMap((data) => {
    if (!data) {
      return Observable.throw(new NoDataFoundError());
    }
    return Observable.forkJoin(
      this.service.getData2(id2),
      this.service.getData3(id3),
    );
  })
  .subscribe(
    ([data2, data3]) => {
      this.data2= data2;
      this.data3= data3;
    },
    (err) => {
      if (err instanceof NoDataFoundError) {
        this.router.navigate(...);
      }
    }
  );   

Currently I'm throwing specific error and catching it however I don't like this solution as it's not the only piece of code that could throw an error and the if is not scaling.

I thought about filter or takeWhile operators but I won't be able to execute the redirect.

I also thought about returning Observable.of instead of throwing (in line 4) but then I would have to do the if in subscribe which also smells.


回答1:


You can execute this.router.navigate and return Observable.empty() inside .flatMap. This way you will have a single if statement.

.flatMap(data => {
  if (!data) {
    this.router.navigate(...);
    return Observable.empty();
  }
  return (...);
})

But usually Observables should be lazy and pure(free of side effects) this will make them predictable and easy to compose. Side effects should be performed only by subscriber.

In your specific case, it seems like the proper solution would be to put this logic in the route guard, like described here - https://stackoverflow.com/a/39162538/3772379



来源:https://stackoverflow.com/questions/47610150/rxjs-condition-inside-flatmap

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!