web-dev-qa-db-fra.com

Angular navigation du routeur à l'intérieur de l'effet NgRx

Le routeur Angular Angular a-t-il des restrictions à utiliser dans un effet NgRx?

Je viens de commencer à apprendre NgRx et j'ai le code suivant:

@Effect() public authenticate$ = this.actions$
    .ofType(authenticationActions.AUTHENTICATE)
        .switchMap((action: AuthenticateAction) => this.authenticationService.authenticate(action.payload)
            .map((data: TokenData) => {
                const user: User = {
                    token: data.token,
                    username: 'dummy',
                };
                console.log(data);
                this.router.navigateByUrl('/');
                return new authenticationActions.AuthenticateSuccessAction(user);
            })
            .catch(error => { console.log(error); return Observable.throw(error); })
        );

La console enregistre la variable de données et l'action AuthenticateSuccessAction est déclenchée, donc la ligne du routeur est en cours d'exécution mais la navigation n'a pas lieu.

7
RBasniak
@Effect() public authenticate$ = this.actions$.pipe(
    ofType(authenticationActions.AUTHENTICATE),
     map(action => action.payload),
    exhaustMap((auth: any) => 
      this.authenticationService.authenticate(auth)
        .map((data: TokenData) => {
            return user: User = {
                token: data.token,
                username: 'dummy',
            };
        }).catch(error => { console.log(error); return Observable.throw(error); 
       }).pipe(
          map(user =>new authenticationActions.AuthenticateSuccessAction(user))
        )
    );)

  @Effect({ dispatch: false })
   loginSuccess$ = this.actions$.pipe(
     ofType(authenticationActions.AuthenticateSuccessAction),
     tap(() => this.router.navigate(['/']))
   );

Utilisez exhaustMap et lorsque vous distribuez l'action "AuthenticateSuccessAction", effectuez un autre effet pour la redirection.

Personnellement, j'aime séparer tous les services des effets, puis vous pouvez utiliser l'opérateur catchError () après la connexion réussie pour envoyer une autre action en cas d'échec de connexion.

espérons que cela fonctionne. PS: Je n'ai pas vérifié cette réponse mais la logique est comme ça.

16
m.akbari

Il devrait y avoir une approche permettant de ne pas créer d'effet séparé pour la redirection, quelque chose comme

this.actions$.pipe(
  ofType(authenticationActions.AUTHENTICATE),
  switchMap(action =>
    this.authenticationService.authenticate(action.payload).pipe(
      map(data => new authenticationActions.successAction(data)),
      tap(() => this.router.navigate(['/'])),
      catchError(error => new authenticationActions.failAction(error))
    )
);

Le fait est que tap ne sera pas invoqué si l'appel de service a échoué, map et tap seront ignorés en faveur de catchError si le cas d'échec .

1
dhilt