Here is my app.state.ts
export interface AppState {
getCards: Card[];
getFlippedCards: Card[];
currentPlayer: boolean;
firstPlayerScore: number;
secondPlayerScore: number;
flipped: boolean;
error: string;
}
export const initialState: AppState = {
getCards: [],
getFlippedCards: [],
currentPlayer: false,
firstPlayerScore: 0,
secondPlayerScore: 0,
flipped: false,
error: '',
};
const appState = (State: AppState) => State;
export const getCards = createSelector(appState, (state) => state.getCards);
export const getFlippedCards = createSelector(
appState,
(state) => state.getFlippedCards
);
export const currentPlayer = createSelector(
appState,
(state) => state.currentPlayer
);
export const firstPlayerScore = createSelector(
appState,
(state) => state.firstPlayerScore
);
export const secondPlayerScore = createSelector(
appState,
(state) => state.secondPlayerScore
);
export const flipped = createSelector(appState, (state) => state.flipped);
export const error = createSelector(appState, (state) => state.error);
app.module.ts:
imports: [
BrowserModule,
AppRoutingModule,
StoreModule.forRoot({ AppReducer }),
],
app.reducer.ts
export function AppReducer(state = initialState, action: AppActions): AppState {
switch (action.type) {
case ActionTypes.Load:
return { ...state, getCards: action.payload };
case ActionTypes.ToggleFlip:
....
app.actions.ts
export enum ActionTypes {
Load = 'Load Cards',
ToggleFlip = 'Flip a Card',
}
export class ToggleFlip implements Action {
readonly type = ActionTypes.ToggleFlip;
constructor(public payload: Card) {}
}
export class Load implements Action {
readonly type = ActionTypes.Load;
constructor(public payload: Card[]) {
console.log('load app.actions ', payload);
}
}
export type AppActions = ToggleFlip | Load;
However, I cannot retrieve any information from the store, this.cards$ is undefined from the selector:
app.component.ts
this.store.dispatch(new fromActions.Load(this.cards));
this.cards$ = this.store.pipe(select(fromState.getCards));
The store is being populated with the array just fine. So there is no problem there, I think my app.state.ts selectors are not set up properly (or maybe the part in app.module.ts). Where did I do wrong?
By declaring your store like this: StoreModule.forRoot({ AppReducer }), as far as I can tell, your state object would look like this:
{
AppReducer: {
getCards: ...,
getFlippedCards: ...,
}
}
Meaning that const appState = (State: AppState) => State; will return the above object, which does not have any other properties, except AppReducer.
As a rule of thumb, each property(slice) of the store must be associated with a reducer. So, if you have: StoreModule.forRoot({ a: aReducer, b: bReducer, c: cReducer }), your state would look like this:
{
a: ...,
b: ...,
c: ...,
}
I think of the entire state as a pie and each slice is a feature.
A quick fix would be this:
export interface AppState {
featureName: {
getCards: Card[];
getFlippedCards: Card[];
currentPlayer: boolean;
firstPlayerScore: number;
secondPlayerScore: number;
flipped: boolean;
error: string;
}
}
const featureState = createFeatureSelector<AppState>('featureName');
export const getCards = createSelector(featureState, (state) => state.getCards);
/* ... */
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With