Search code examples
angulartypescriptngrx

Converting @Effect to createEffect NGRX


I am converting an @Effect (which obviously is now deprecated), to a createEffect, however I am seeing some errors I was not expecting and can't understand why.

Previous effect:

  @Effect({ dispatch: false })
  LoginSuccess: Observable<any> = this.actions.pipe(
    ofType(AuthActions.SUCCESSFUL_LOGIN),
    tap((user) => {
      localStorage.setItem('jwt', user.payload.token);
      this.router.navigateByUrl('/');
    })
  );

New Effect:

  loginSuccess$ = createEffect(() => {
    return this.actions.pipe(
      ofType(AuthActions.SUCCESSFUL_LOGIN),
      tap((user) => {
        localStorage.setItem('jwt', user.payload.token);
        this.router.navigateByUrl('/');
      })
    ),
    { dispatch: false }
  });

The errors:

Property 'payload' does not exist on type 'never'.

Argument of type '() => { dispatch: boolean; }' is not assignable to parameter of type '() => EffectResult'.

In anyone can point out my obvious error, I'd be grateful.


Solution

  • Pass in the actual actionCreator returned from createAction to ofType ie:

    export const successfulLoginAction = createAction('[User] Login Succeeded', props<{ token: string }>());
    
        return this.actions.pipe(
          ofType(successfulLoginAction),
          tap((action) => {
              localStorage.setItem('jwt', action.token);
          ...
    

    If you want to use old style action classes, then you need to pass the action type to ofType:

        return this.actions$.pipe(
          ofType<LoginSuccess>(AuthActions.SUCCESSFUL_LOGIN),
          tap((action) => {
            localStorage.setItem('jwt', action.payload.token);
          ...
      );