首页 > 解决方案 > How to simplify NgRx effects? Only difference the service method they call-

问题描述

I have got the following code from an NgRx effects file:

  registerUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.registerUser),
      switchMap(action => {
        return this.authService.registerWithEmailAndPassword(action.userCredentials).pipe(
          map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
          catchError(error => of(AuthStoreActions.setError({ error })))
        );
      })
    )
  );
  loginUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.loginUser),
      switchMap(action => {
        return this.authService.loginWithEmailAndPassword(action.userCredentials).pipe(
          map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
          catchError(error => of(AuthStoreActions.setError({ error })))
        );
      })
    )
  );

After the service call both are doing the same thing. How could eleminate the repeatness? I have got an other sibling effects aswell which does more after receiving the response from the server than this example, but apart from the method they call, they are doing the same thing.

标签: angulartypescriptngrxngrx-storengrx-effects

解决方案


With the pipe function, you can bottle up those auth store operators in one.

The power of function composition!

import { pipe } from "rxjs";

const handleAuth = pipe(
  map(() => AuthStoreActions.authSuccess({ navigateTo: "authentication/restaurant" })),
  catchError(error => of(AuthStoreActions.setError({ error }))));

loginUser$: Observable<Action> = createEffect(() =>
  this.actions$.pipe(
    ofType(AuthStoreActions.loginUser),
    switchMap(action => this.authService.loginWithEmailAndPassword(action.userCredentials).pipe(handleAuth)));

registerUser$: Observable<Action> = createEffect(() =>
    this.actions$.pipe(
      ofType(AuthStoreActions.registerUser),
      switchMap(action => this.authService.registerWithEmailAndPassword(action.userCredentials).pipe(handleAuth)));

推荐阅读