Search code examples
angularrxjsngrxngrx-effects

ROOT_EFFECTS_INIT is never called


I have an effect in ngrx called SelfEffect

I want it to do the following when loaded :

  @Effect()
  init$ = this.actions$.pipe(
    ofType(ROOT_EFFECTS_INIT),
    concatMap(() => of().pipe(withLatestFrom(this.store.pipe(select(IsAuthenticated))))),
    switchMap(([_, isLogged]) => (isLogged ? of(new GetSelfRequest()) : EMPTY))
  );

Now, this effect is registered in app.store.module

@NgModule({
  imports: [
    StoreModule.forRoot(appReducers, { metaReducers }),
    EffectsModule.forRoot([AuthEffects, AlertEffects, SelfEffects]),
    StoreRouterConnectingModule.forRoot({
      serializer: RouterSerializer,
      navigationActionTiming: NavigationActionTiming.PostActivation,
    }),
    StoreDevtoolsModule.instrument({
      name: 'Dev'
     }),
  ],
  providers: [Store],
})

which is called in app.module.ts

@NgModule({
  imports: [
    AppRoutingModule,
    AppStoreModule,
    ...
  ]

Why does this event never dispatch ? is it because I use a router store ?


Solution

  • The problem is in the

    of().pipe(withLatestFrom)
    

    The empty of() will never emit an event, therefore the withLatestFrom cannot emit either.

    The whole line can be simplified to a single switchMapTo (concatMap is dangerous in the case the ROOT_EFFECTS_INIT could fire more times - it would multiply the action each time).

      @Effect()
      init$ = this.actions$.pipe(
        ofType(ROOT_EFFECTS_INIT),
        switchMapTo(this.store.pipe(select(IsAuthenticated))),
        switchMap((isLogged) => (isLogged ? of(new GetSelfRequest()) : EMPTY))
      );
    

    PS: I'd consider adding take(1) somewhere (depends on what you want to achieve) into the pipe(s) so you have complete control on what is happening.