NgrX effect redirect angular

Viewed 619

I have effect like this

  createAssignment$ = createEffect(() =>
    this.action$.pipe(
      ofType(AssignmentActions.createAssignment),
      switchMap((action) =>
        this.assignmentService.createNewAssignment(action.assignmentTo).pipe(
          map((data) => AssignmentActions.createAssignmentSuccess({ createdAssignment: data }),
            catchError((error) => of(error))),
        )
      )
    ));

What I need is to redirect user to new page based on value from data, something like this

 this.router.navigate(data);

But I dont know when to do that, to make new effects or just under action? Anyone got similar problem?

2 Answers

You can do that by using the tap operator after map, which will be invoked only if the operation succeeded:

createAssignment$ = createEffect(() =>
    this.action$.pipe(
        ofType(AssignmentActions.createAssignment),
        switchMap((action) =>
            this.assignmentService
                .createNewAssignment(action.assignmentTo)
                .pipe(catchError((error) => of(error)))
        ),
        map((data) => AssignmentActions.createAssignmentSuccess({ createdAssignment: data })),
        tap((data) => { this.router.navigate(data); })
    )
);

I would recommend creating separate effect for redirect. New Effect encapsulates own logic and makes it also reusable. Listening for multiple actions in effect should not be uncommon pattern.

  1. Inject Router in your Effects class assignemnts.effects.ts

    constructor( ... private readonly router: Router) {}

  2. Your Code Your code

Redirect Effect that listens to your AssignmnetActions.CreateAssignemntSuccess({assignment}); Scenario: It will take the ID of the user in the assignment and redirect to /user-details page.

userPageRedirect$ = createEffect(() =>
    this.actions$.pipe(
      ofType(AssignmnetActions.CreateAssignemntSuccess()),
      concatMap((action) => of(action).pipe(withLatestFrom(this.store.pipe(select(getSelectedUserId))))),
      fetch({
        run: (action, userId: number) => {
          this.router.navigate([`/user-details/${userId}`]);
        },
      })
    ));
Related