0
votes

I am developing functionality where dispatch is not needed if loading or loaded values in state are true. I am facing issues with checking BOTH values in the store before dispatching. Is there a way to combine two selectors before dispatching action?

I need can have two possible forms of a State:

State = {
list: [],
loading: true,
loaded: false
}

or

State = {
list: [],
loading: false,
loaded: true
}

I am trying to do it with two selectors (method in my component):

 checkStore() {
    return this.store.select(getLoading).pipe(
      tap(loading => {
        if (!loading) {
          this.store.select(getLoaded).pipe(
            tap(loaded => {
              if (!loaded) {
                this.store.dispatch(fetchList({ payload: {something} }));
              }
            }),
            take(1)
          );
        } else {
          this.store.dispatch(fetchList({ payload: {something} }));
        }
      }),
      take(1)
    );
  }

And then calling such method in ngOnInit() As i see nothing is being dispatched in this way. Maybe you have suggestions for implementing such functionality?

1
but nothing is subscribing to the above; if no one is subscribing then it wont kick off. If you want the Observable to fire, then you first need to subscribe to it. Unless you have not pasted the subscription part here? - Robert Dinaro
@RobertDinaro I am subscribing it on ngOnInit, just have not pasted the code - me_gone

1 Answers

4
votes

You can combine two selectors with RxJs' combineLatest. As per its docs

Combines multiple Observables to create an Observable whose values are calculated from the latest values of each of its input Observables.

combineLatest([
  this.store.pipe(select(getLoading)),
  this.store.pipe(select(getLoaded)),
])
  .pipe(take(1))
  .subscribe(
    ([loading, loaded]: [boolean, boolean]) => {
      if (!loading && !loaded) {
        this.store.dispatch(fetchList({payload: {something}}));
      }
    }
  );

combineLatest returns a new Observable that emits an array with the latest values from the input Observables, so you can deconstruct them [loading, loaded].
Then you can subscribe to it and check for its values.

take(1) as you used will get the first value emitted from combineLatest and then completes. Considering your store has an initial state, both selectors will return values on init.