hankphone
hankphone

Reputation: 123

ngrx 4 selectors returning entire state instead of sub states

For some reason all of my selectors are returning the entire state object instead of the sub states that I thought they should. For example, I am trying to just return the customer State from reducers/customer.ts but instead I get an object with the entire State from index.ts.

I choose the particular structure below after examining the ngrx example app from github, clearly I am doing something(s) wrong.

File structure: enter image description here

Here is actions/customer.ts:

import { Action } from '@ngrx/store';
import { State } from '../reducers/customer';

export enum CustomerActionTypes {
  Add = '[Customer] Add Selected Customer to Store'
}

export class Add implements Action {
  readonly type = CustomerActionTypes.Add;
  constructor(public payload: State) {
    console.log("from action: " + JSON.stringify(payload,null,2));
  }
}

export type CustomerActions = Add

And reducers/customer.ts:

import { ActionReducer, Action } from '@ngrx/store';
import { CustomerActionTypes, CustomerActions } from '../actions/customer';

export interface State {
  name: string;
  status: string;
  phone: string;
  stage: string;
  type: string;
  id: string;
  street: string;
  city: string;
  postalCode: string;
  email: string;
  state: string;
}

export function reducer(
  state: State,
  action: CustomerActions
): State {
  switch (action.type) {
    case CustomerActionTypes.Add:
      return action.payload

    default:
      return state;
  }
}

export const getCustomerState = (state: State) => state;

And reducers/index.ts:

//For reducers map
import * as fromMainNav from './main-nav-ui';
import * as fromTradeUI from './trade-ui';
import * as fromAppts from './appointments';
import * as fromCustomer from './customer';


//Whole application state
export interface State {
  mainNavUI: fromMainNav.State;
  tradeUI: fromTradeUI.State;
  appointments: fromAppts.State;
  selectedCustomer: fromCustomer.State;
}

//Reducer map
export const reducers = {
  mainNavUI: fromMainNav.reducer,
  tradeUI: fromTradeUI.reducer,
  appointments: fromAppts.reducer,
  selectedCustomer: fromCustomer.reducer
};

And imports in app.module.ts:

imports: [
    ...
    StoreModule.forRoot(reducers)
  ],

And lastly how I am am wiring it up in a component and using selector:

...
import * as fromCustomer from '../../../shared/state/reducers/customer';
...

public cust$: Observable<fromCustomer.State>;

constructor(
    ...
    public ngrxStore: Store<fromCustomer.State>
  ) {
      this.cust$ = ngrxStore.select(fromCustomer.getCustomerState);
    }

Any help would be appreciated, thanks!

Upvotes: 4

Views: 1911

Answers (2)

red_Coder
red_Coder

Reputation: 95

Salem has given you a great solution, but the root cause of your issue was this line here in the app component.

this.cust$ = ngrxStore.select(fromCustomer.getCustomerState);

And your fromCustomer.getCustomerState was defined as below:

export const getCustomerState = (state: State) => state;

Since ngrxStore.select will always returns you the root state, of course you will still just get the root state based on how you defined this getCustomerState function.Your getCustomerState function does not do any transformation, it just returns whatever that is passed through.

Upvotes: 0

Salem Ouerdani
Salem Ouerdani

Reputation: 7886

Try using createFeatureSelector inside reducers/index.ts to start from a top level feature state:

export const getAppState = createFeatureSelector<State>('wholeApp');

Then use it in a different selector to access your customer reducer:

export const getCustomer = createSelector(
  getAppState,
  (state: State) => state.selectedCustomer
);

From there you can keep going deeper into your state by chaining selectors, as example, if your component just needed to know about a customer's email adresse, it could just subscribe to this:

export const getEmail = createSelector(
   getCustomer,
   (state: fromCustomer.State) => state.email
);

For more details (and examples) I recommend checking this great article by Todd Motto:

https://ultimatecourses.com/blog/ngrx-store-understanding-state-selectors

Upvotes: 2

Related Questions