angulartypescriptreduxngrxngrx-store

Array subscription gets triggered when other parts of the state change in NgRx


I have locations and activeLocationsIds array. locations array contains all locations, activeLocationsIds contains IDs from active locations (not objects, only IDs that are 1..1 with locations IDs).

Anytime other parts of the state get changed, e.g., selectedOrder, the subscription for activeLocationsIds gets triggered.

This is my state:

export interface ICustomerHierarchyState {
    locations: ILocation[],
    activeLocationsIds: string[];
    selectedOrder: number;
}

These are selectors for fetching activeLocations:

export const getActiveLocationsIds = createSelector(
    getCustomerHierarchyState,
    state => state.activeLocationsIds
)

export const getActiveLocations = createSelector(
    getCustomerHierarchyState,
    getActiveLocationsIds ,
    (state, getActiveLocationsIds ) => state.locations.filter(x => getActiveLocationsIds.includes(x.locationId)) ?? []
)

This is the activeLocationsIds reducer:

on(CustomerHierarchyPageActions.setActiveLocations, (state, action): ICustomerHierarchyState => {
        return {
            ...state,
            activeLocationsIds: action.locationsIds
        }
    })

This is the activeLocationsIds action:

export const setActiveLocations = createAction(
    '[Customer-Hierarchy Page] Set ActiveLocations',
    props<{ locationsIds: string[] }>()
)

Also, here is the reducer for clearing selectedOrder:

on(CustomerHierarchyPageActions.clearSelectedOrder, (state): ICustomerHierarchyState => {
        return {
            ...state,
            selectedOrder: -1
        }
    })

Finally, this is getActiveLocations subscription:

this.subscriptions.add(
      this.store.select(getActiveLocations)
        .subscribe(
          activeLocations => {
            this.activeLocations = activeLocations;
          }
        ));

Anytime I dispatch a different action for example this.store.dispatch(CustomerHierarchyPageActions.clearSelectedOrder());, subscription for the activeLocations gets triggered.

Why is that?

In my reducer, I only update selectedOrder (to -1 value) so I don't know why getActiveLocations subscription gets triggered...


Solution

  • Here is your answer: Ngrx selector not triggering when the reducer alters the slice

    This check is a simple reference check (===). Because you're modifying the state directly, the reference stays the same

    You are creating a new object, this means a new reference

    UPDATE:

    The easiest solution for you would be to use distinctuntilchanged operator with custom comparer (https://www.learnrxjs.io/learn-rxjs/operators/filtering/distinctuntilchanged)