Harry_C
Harry_C

Reputation: 177

RxJS Observables - How to condition observable returns

I am new to Observables and RxJs and I want to condition the return. If the first selector returns a certain value I want an observable from the second selector. But if the first selector does not return that particular value I want to return false instead (of(false)). I have come this far but this returns an Observable<Observable>. It shouldn't be nested. How do I do this? Here is the code this far:

       const condition$: Observable<boolean> =
        this.store.pipe(
            select(this.firstSelector.get()),
            map(item=> {
                if (item !== X) {
                    return of(false)
                } else {
                    return this.store.pipe(select(this.secondSelector.hasValue()))
                }
            })
        )

Upvotes: 1

Views: 2395

Answers (2)

Barremian
Barremian

Reputation: 31105

You're almost there. You should be using a higher order mapping operator like switchMap to return an observable. map is used to transform and return data from the observable.

const condition$: Observable<boolean> = this.store.pipe(
  select(this.firstSelector.get()),
  switchMap(item =>
    (item !== X)
      ? of(false)
      : this.store.pipe(select(this.secondSelector.hasValue()));
  )
)

Upvotes: 4

So if you want to use if-else construct like in your snippet you can do the following

 const condition$: Observable<boolean> =
        this.store.pipe(
            select(this.firstSelector.get()),
            switchMap(item=> {
                if (item !== X) {
                    return of(false)
                } else {
                    return this.store.pipe(select(this.secondSelector.hasValue()))
                }
            })
        )

The switchMap operator will return a new observable.

Another way of using if-else would be with the partition operator

const condition$ = this.store.pipe(select(this.firstSelector.get()))
            

const [_differentItem$, _sameItems$] = partition(condition$, (item) => item !== X);

const differentItem$ = _differentItem$.pipe(mapTo(false))
const sameItem$ = _differentItem$.pipe(switchMap(() => this.store.pipe(select(this.secondSelector.hasValue()))

In the second example partition operator will create two observables where the first one (_differentItem$) will emit when the condition evaluetes to true and the second one (_sameItems) when it evaluates to false

After that I'am creating two pipe-chains that contain the rest of the logic, in the case of the differentItem$ im directly using the mapTo operator which will map all values emiited trough it to false and for the second observable sameItem$ I'm saying whenver your source emits (e.g. trough the stream passes item === X) return new observable that is pointing to the secondSelector.

Upvotes: 2

Related Questions