Steve S.
Steve S.

Reputation: 541

Selector for NgRx root store

This is my first shot to NgRx Store so get ready for newbie question...

Everything I put in place so far work but one part of my code doesn't seems "right".

My store is build with 2 interfaces (token.model.ts):

export interface Keyring {
  jwt: string;
  status: string;
}

export interface TokenState {
  readonly keyring: Keyring;
}

The store sit in the root of the app (app.module.ts):

...    
StoreModule.forRoot({ security: keyringReducer }),
...

Note here the name in the map... security

The selector I used to access my store in my component is like this and it work:

this.token$ = store.select<any>((state: any) => state.security.keyring.jwt);

Now, this is where it doesn't feel right since nothing is type and I want to replace it with a "clean" selector. So it tried this :

const selectState = (state: TokenState) => state.keyring;
export const selectJwt = createSelector(
         selectState,
         (state: Keyring) => state.jwt
       );
...

this.token$ = store.select(selectJwt);

And for sure, this doesn't work (state is undefined)! And I can see why, the "security" object is missing in the equation but I can't find a way to include it in the declaration of my selector. It's not part of my interface and just a literal in the registration of my store.

So, my question is : What is the proper selector to access a root store???

Thanks!

UPDATE

This is the best I can do using the createFeatureSelector even if the store is forRoot:

const selectStore = createFeatureSelector<TokenState>('security');
export const selectJwt = createSelector(
  selectStore,
  (state: TokenState) => state.keyring.jwt
);

Upvotes: 0

Views: 1802

Answers (1)

timdeschryver
timdeschryver

Reputation: 15505

But it seems strange to use a method for a Feature store on the root store.

I get the confusion, but featureSelector isn't really bound to features it's just there to select a slice from the root object. It's syntactic sugar for const selectSecurity = (state) => state.security.

What I tend to use currently (to decrease the complexity) is just use StoreModule.forRoot({}) to create the store but to not register any reducers. To register reducers, I'm using StoreModule.forFeature('security', securityReducer). From my experience this setup is causes less friction for most devs. The outcome of both setups is equal.

Upvotes: 2

Related Questions