Reputation: 2256
I have imported NgRx into my application:
imports: [
StoreModule.forRoot(reducers, {})
],
My reducers are registered in /ngrx/reducers/index.ts
as shown:
import { ActionReducerMap } from "@ngrx/store";
import { HeroReducers } from "../home/hero/hero.reducers";
export interface State {};
export const reducers: ActionReducerMap <State> = {
heroReducers:HeroReducers
}
HeroReducer is shown here:
import { createReducer, on } from '@ngrx/store';
import * as heroActions from "./hero.actions";
const initialState = {
heroSlides: [
{
img: "Screenshot from 2024-01-20 12-38-48.png",
status: "active"
},
]
}
export const HeroReducers = createReducer(initialState,
on(heroActions.StoreHero, (state, action) => {
console.log('Storesubjects.subjects', action)
return {
...state,
// subjects: action.subjects,
};
}),
)
The action file for the reducer is shown here:
import { createAction, props } from "@ngrx/store";
export const StoreHero = createAction(
'[Store Hero] Store Hero'
)
I inject the store in my component as shown here:
constructor(
private store:Store<{heroReducers}>
) {}
In ngOnInit of my component, I subscribe to the reducer as shown. I also dispatch a call to the reducer.
ngOnInit() {
this.subscribeToReduxStores();
this.store.dispatch(StoreHero());
}
private subscribeToReduxStores = () => {
const hero$ = this.store.select((state) => {
console.log('state', state)
return state
})
hero$.subscribe(hero => {
// this.hero = hero;
console.log('hero', hero)
})
}
I get the following results of the console.log calls:
state {}
hero {}
state {}
The state is an empty object and does not contain the heroSlides array of the initialState of the HeroReducers.
Upvotes: 0
Views: 57
Reputation: 2907
A couple of observations that potentially fix your issue.
Your initialState
for HeroesReducer
does not have a type defined. You can define what shape is going to have this particular heroes slice
like the following:
heroes.reducer.ts
export interface HeroState {
slides: { img: string; status: string}[];
}
const initialState: HeroState = {
slides: [];
}
export const HeroesReducers(initialState, ...);
Where you have your ActionReducerMap
, there is an empty interface called State
, I feel like you could use that one in order to wrap the whole store slices definition, like the following:
import {HeroState} from '../heroes/heroes.reducer.ts';
export interface State {
heroes: HeroState;
villains: VillainsState; // you could add more slices here
biography: BiographyState; // you could add more slices here
}
Having that, now you can inject your store with the proper data type as:
some.component.ts
import {State} from '../interfaces/store.interface.ts'; // this is just an example
constructor(private store: Store<State>) {}
I feel like your current code fails to know what the store has since you are defining the store dataType as Store<{heroReducers}>
, from where are you taking this heroReducers
? Also, make sure to use redux dev tools browser extension to see what you have in the store initially, validating if the heroes
slice is defined and also to see every action triggered and monitor what happens with the data.
Additionally, the callback function for selecting
data from the store should be defined in the proper selectors file using createSelector
function, for example, heroes.selectors.ts
rather than having that logic in your component.
heroes.selectors.ts
export const selectHeroes = createSelector(state => state.heroes);
For more information about selectors
, I recommend reading the official docs
Upvotes: 0