2

I have a selector:

const mySelector = createSelector(
  selectorA,
  selectorB,
  (a, b) => ({
    field1: a.field1,
    field2: b.field2
  })
)

I know the selector is evaluated when any of its inputs change.

In my use case, I need to control "mySelector" by a third selector "controlSelector", in the way that:

  • if "controlSelector" is false, "mySelector" does not evaluate a new value even in the case "selectorA" and/or "selectorB" changes, and returns the memoized value

  • if "controlSelector" is true, "mySelector" behaves normally.

Any suggestions?

SFA
  • 21
  • 4

2 Answers2

0

Selectors are pure functions..its will recalculate when the input arguments are changed.

For your case its better to have another state/object to store the previous iteration values. You can pass that as selector and based on controlSelector value you can decide what you can return.

state : {
  previousObj: {
    ...
  }
}

const prevSelector = createSelector(
  ...,
  (state) => state.previousObj
 )

const controlSelector = createSelector(...);

const mySelector = createSelector(
  controlSelector,
  prevSelector,
  selectorA,
  selectorB,
  (control, a, b) => {
    if(control) {
      return prevSelector.previousObj
    } else {
      return {
        field1: a.field1,
        field2: b.field2
      };
    }
  } 
)
rijin
  • 1,709
  • 12
  • 21
0

Sorry for the delay... I have finally solved the issue not using NGRX selectors to build up those "higher selectors" and creating a class with functions that use combineLatest, filter, map and starWith

getPendingTasks(): Observable<PendingTask[]> {
  return combineLatest(
    this.localStore$.select(fromUISelectors.getEnabled),
    this.localStore$.select(fromUISelectors.getShowSchoolHeadMasterView),
    this.memStore$.select(fromPendingTaskSelectors.getAll)).pipe(
      filter(([enabled, shmView, tasks]) => enabled),
      map(([enabled, shmView, tasks]) => {
        console.log('getPendingTasks');
        return tasks.filter(task => task.onlyForSchoolHeadMaster === shmView);
      }),
      startWith([])
    );
}

Keeping the NGRX selectors simple and doing the heavy lifting (nothing of that in this example, though) in this kind of "selectors": - will generate an initial default value (startWith) - will not generate new value while filter condition fails (that is, when not enabled, any changes in the other observables do not fire a new value of this observable)

SFA
  • 21
  • 4