im trying to work with ngrx and angular. My Authenfication works but my product store doesn work because nothing happens:
I working with modules:
const routes: Routes = [
{
path: '',
redirectTo: 'home',
pathMatch: 'full'
},
{
path: 'home',
loadChildren: () => import('src/app/home/home.module')
.then(module => module.HomeModule)
}
]
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
BrowserAnimationsModule,
RouterModule.forRoot(routes),
EffectsModule.forRoot([]),
StoreModule.forRoot({}),
StoreDevtoolsModule.instrument({
maxAge: 25,
logOnly: environment.production
}),
TopBarModule,
AuthModule,
HomeModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
And in my home module i inject the effectservices:
const routes: Routes = [
{
path: '',
component: HomeComponent
}
]
@NgModule({
declarations: [
HomeComponent
],
imports: [
CommonModule,
RouterModule.forChild(routes),
EffectsModule.forFeature([
GetCategoryEffectsService,
GetProductEffectService
]),
StoreModule.forFeature('category', categoryReducers),
StoreModule.forFeature('product', productReducers),
],
providers: [
GetCategoriesService,
GetProductsService
]
})
export class HomeModule { }
My redux dont do anything with this module and my effect doesnt work:
@Injectable()
export class GetProductEffectService {
constructor(
private actions$: Actions,
private getProductsService: GetProductsService
) { }
getProducts$ = createEffect( () =>
this.actions$.pipe(
ofType(getProductAction),
switchMap(() => {
return this.getProductsService.getProducts().pipe(
map((products) => getProductActionSuccess({products}))
)
})
))
}
if i subscribe the the method to get products without my store i gets all products...
my Actions look like this:
export const getProductAction = createAction(
ProductActionTypes.PRODUCT_ACTION
);
export const getProductActionSuccess = createAction(
ProductActionTypes.PRODUCT_ACTION_SUCCESS,
props<{products: ProductInterface[]}>()
);
export const getProductActionFailure = createAction(
ProductActionTypes.PRODUCT_ACTION_FAILURE,
props<{error: BackendErrorsInterface}>()
);
export enum ProductActionTypes {
PRODUCT_ACTION = '[Product] product action',
PRODUCT_ACTION_SUCCESS = '[Product] product action success',
PRODUCT_ACTION_FAILURE = '[Product] product action failure',
}
My reducers are similar to my working reducers but here is the code:
const initialState: ProductStateInterface = {
data: null,
error: null,
isLoading: false,
isSubmitting: false
}
const reducers = createReducer(
initialState,
on(
getProductAction,
(state): ProductStateInterface => ({
...state,
isLoading: true,
error: null
})
),
on(
getProductActionSuccess,
(state, action): ProductStateInterface => ({
...state,
data: action.products,
isLoading: false,
error: null
})
),
on(
getProductActionFailure,
(state, action): ProductStateInterface => ({
...state,
data: null,
isLoading: false,
error: action.error
})
)
);
export function productReducers(state: ProductStateInterface, action: Action){
return reducers(state, action);
}
i select the actions in my product selector File:
export const actionFeatureSelector = createFeatureSelector<
AppStateInterface,ProductStateInterface>('product');
export const productIsLoadingSelector = createSelector(
actionFeatureSelector,
(productState: ProductStateInterface) => productState.isLoading
);
export const getProductsSelector = createSelector(
actionFeatureSelector,
(productState: ProductStateInterface) => productState.data
);
export const productErrorSelector = createSelector(
actionFeatureSelector,
(productState: ProductStateInterface) => productState.error
);
export const productIsSubmittingSelector = createSelector(
actionFeatureSelector,
(productState: ProductStateInterface) => productState.isSubmitting
);
Nothing happens with this store. Here is my component:
ngOnInit(): void {
this.initializeValues();
}
private initializeValues(): void {
this.store.pipe(select(getProductsSelector)) //.subscribe(test => console.log(test));
this.categories$ = this.store.pipe(select(categorySelector));
this.isLoading$ = this.store.pipe(select(isLoadingSelector));
}
CodePudding user response:
You have an effect which triggers only when getProductAction
is dispatched:
getProducts$ = createEffect( () =>
this.actions$.pipe(
ofType(getProductAction),
switchMap(() => {
return this.getProductsService.getProducts().pipe(
map((products) => getProductActionSuccess({products}))
)
})
))
However, you never actually dispatch the action, so the effect will never be triggered.
I suggest you dispatch the action in your component:
ngOnInit(): void {
this.initializeValues();
this.store.dispatch(getProductAction()); // <-- here you trigger the effect to fetch the products
}
private initializeValues(): void {
this.store.pipe(select(getProductsSelector)) //.subscribe(test => console.log(test));
this.categories$ = this.store.pipe(select(categorySelector));
this.isLoading$ = this.store.pipe(select(isLoadingSelector));
}