老实说,我不太能找出问题所在,但我会写一些不同的东西,所以我会建议这些,希望它能重构问题。还console.log
是异步的,所以不要相信它会以正确的顺序登录。
当使用 RxJS 时,我建议倾向于功能性的并且不使用静态成员变量来传递值。您应该致力于链接所有内容,这样就不会出现任何意外的异步副作用。
这未经测试,但应该是正确的。检查内嵌评论。希望能帮助到你。
private login() {
this.authService.login(this.loginForm.valid)
.subscribe((data: any) => { // no need for pipe and map
console.log("First");
this.router.navigate(['/app']);
})
}
export class AuthService {
public isLoggingIn = new BehaviorSubject<boolean>(false);
public isLoggedIn = new BehaviorSubject<boolean>(false);
constructor() { }
// You were returning Observables, not booleans. Help TypeScript help you - don't use 'any'.
public login(loginData: { username: string, password: string }): Observable<boolean> {
this.clearData();
this.isLoggingIn.next(true);
return this.http.post(environment['baseURL'] + '/api/auth/login', loginData)
.pipe(
map(
(data: any) => {
if (data['token'] && data['user']) {
this.isLoggedIn.next(true);
this.isLoggingIn.next(false);
this.token = data['token'];
localStorage.setItem('token', this.token);
localStorage.setItem('usermeta', JSON.stringify(this.userData));
return true // no 'of'
} else {
return false // no 'of'
}
}
),
catchError((error: any) => {
this.isLoggingIn.next(false);
return of(false) // catchError expects a new observable so we do use 'of' here.
})
)
}
}
export class AuthGuard implements CanActivate {
constructor(
private router: Router,
private authService: AuthService
) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean | UrlTree> {
return this.authService.isLoggedIn.pipe(
// always important to handle the transition state
// skip if currently logging in (assumes a second emission once logged in)
skipUntil(this.authService.isLoggingIn.pipe(filter(isLoggingIn => !isLoggingIn)))
).pipe(
map(isLoggedIn => {
if (isLoggedIn) {
return true;
} else {
return this.router.createUrlTree(['/login'], { queryParams: { returnUrl: state.url } })
}
})
)
}
}