Home > front end >  NgRX Effect is not workling
NgRX Effect is not workling

Time:02-10

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));
  }
  • Related