Search code examples
angularngrx

store.select().subscribe() returns unexpected 'reducer' property inside State Data Structure


I just started trying out NGRX by working through a tutorial. Everything seems to work so far, except that my state Data Structured gets corrupted somehow and I simply cant find where and how.

My Reducer looks like that:

import * as fromRoot from '../../../state/app.state';
import { createFeatureSelector, createSelector } from '@ngrx/store';

export interface State extends fromRoot.State {
  criteriaLock: CriteriaLockState;
}

export interface CriteriaLockState {
  storeNames: string[];
  selectedStoreName: string;
}

const initialState: CriteriaLockState = {
  storeNames: [],
  selectedStoreName: ''
};

const getCriteriaLockFeatureState =  createFeatureSelector<CriteriaLockState>('criteria-lock');

export const getStoreNames = createSelector(
  getCriteriaLockFeatureState,
  state => state.storeNames
);

export const getSelectedStoreName = createSelector(
  getCriteriaLockFeatureState,
  state => state.selectedStoreName
);

export function reducer(state = initialState, action): CriteriaLockState {
  switch (action.type) {
    case 'SET_STORE_NAMES':
      return {
        ...state,
        storeNames: action.payload
      };
    case 'SET_SELECTED_STORE_NAME':
      return {
        ...state,
        selectedStoreName: action.payload
      };
    default:
      return state;
  }
}

When subscribing to it and trying to access the selectedStoreName via

this.store.pipe(select(fromCriteriaLock.getSelectedStoreName)).subscribe(
         criteriaLock => {
          console.log(criteriaLock)
      }

CriteriaLock is undefined, because the received Data Structure is not

criteria-lock: {
 selectedStoreName: ''
}

but

criteria-lock: {
  reducer: {
   selectedStoreName: ''
  }
}

That means that somehow the reducer function shows up in the state Object. This is not the correct behaviour, right? When I want to access the State in the subscription I have to change the selectors to

export const getStoreNames = createSelector(
  getCriteriaLockFeatureState,
  state => state.**reducer**.storeNames
);

I have no Idea how i am pasting that Property in the state structure, and I have never seen anyone having the same issues. When logging the State Object in the Reducer I receive the correct State. Only here I get this reducer Object. That doesnt seem to be correct, since the Tutorial never mentioned anything like that.

I set the Store Name via:

this.store.dispatch({
      type: 'SET_SELECTED_STORE_NAME',
      payload: storeName
    });

and add the StoreModule in my CriteriaLockModule

imports: [
    CommonModule,
    SharedModule,
    FormsModule,
    StoreModule.forFeature('criteria-lock', { reducer })
  ]



Solution

  • I fixed it:

    The Problem was the parenthisis around the reducer inside the Import from the Module.

    imports: [
        CommonModule,
        SharedModule,
        FormsModule,
        StoreModule.forFeature('criteria-lock', **{ reducer }**)
      ]
    

    should be

    imports: [
        CommonModule,
        SharedModule,
        FormsModule,
        StoreModule.forFeature('criteria-lock', **reducer**)
      ]
    

    Well that just cost me 3 hours :D