Home > other >  Which RxJS operator should I use for getting the first true value?
Which RxJS operator should I use for getting the first true value?

Time:01-27

I am building an Angular application and I have a route, protected with guard. In the guard I have 3 boolean observables.

Each observable returns true or false values, depending on the application state/route etc. I want that the guard returns true, if at least one observable returned true, otherwise - false.

So if at least one observables has evaluated to true - I want that the script should ignore others and the guard should return true

But if it returned false, the guard should look for the second observable and see its evaluated result.

I think that I could use combineLatest:

combineLatest([
   $obs1,
   $obs2,
   $obs3
])

and check result of each observable, but this code will run all three observables without cancellation. the observables may run simultaneously, but they must not complete (if not already completed, if any of observables already returned true, and should return false only if all of observables returns false).

Which operator should I use for getting the first true observable value, and ignoring others, but returning false if all observables returned false?

CodePudding user response:

I think what you are trying to achieve could be done with

merge(
 $obs1.pipe(first()),
 $obs2.pipe(first()),
 $obs3.pipe(first())
).pipe(
  filter(Boolean),
  take(1),
  defaultIfEmpty(false),
)

filter(Boolean) filters out false results, because there are probably yet not handled trues and we should continue searching.

take(1) will take the first true when found, because you really don't care about other trues if there is already one.

and if everything is false, then no events will be emmited by previous operator chain and therefore defaultIfEmpty(false) will put false in that place

CodePudding user response:

combineLatest should be what you want !

combineLatest([obs1$, obs2$, obs3$]).pipe(
  filter(([v1, v2, v3]) => {
    return v1 || v2 || v3 || (!v1 && !v2 && !v3);
  }),
  take(1)
);
  • Related