angular - How do I redirect to different home page when user is logged in Angular?
问题描述
I am trying to make a redirection to the /dashboard
page whenever user is logged in.
The default landing page is /home
, but logged in user home page is /dashboard
.
I have a user service class where I create a sharedUser and it is BehaviorSubject:
public sharedUser= new BehaviorSubject<User>(null);
And then I have initUser method, where I give values to user object. initUserStatus()
method is Observable and fills data from request.
private initUser(accessToken: string): void {
const tokenData = TokenUtil.decodeToken(accessToken);
this.user.email = tokenData.email;
this.initUserStatus().subscribe(
() => this.sharedUser.next(this.user)
);
}
And then I have Guard class where I try to redirect if user data is filled and is actually logged in:
User is logged in when email is initalized, isLoggedIn()
method checks if there is email or not.
export class HomePageGuard implements CanActivate {
constructor(private userService: UserService, private router: Router) { }
public canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<UrlTree | boolean> {
return this.userService.sharedUser.asObservable().pipe(
map(() => {
if (this.userService.isLoggedIn()) {
return this.router.createUrlTree(['/dashboard']);
}
return true;
}
));
}
}
It seems that canActivate
will be in endless loop and it won't go complete and thus it will not redirect to /dashboard page.
How can I fix that? Or what am I missing?
解决方案
The observable returned from a guard does not have to complete. Angular will use the first()
operator anyways.
const canActivateObservables = canActivate.map((c: any) => {
return defer(() => {
const guard = getToken(c, futureARS, moduleInjector);
let observable;
if (isCanActivate(guard)) {
observable = wrapIntoObservable(guard.canActivate(futureARS, futureRSS));
} else if (isFunction<CanActivateFn>(guard)) {
observable = wrapIntoObservable(guard(futureARS, futureRSS));
} else {
throw new Error('Invalid CanActivate guard');
}
return observable.pipe(first()); //
});
});
What you could do in order to avoid the infinite loop is to check in your guard if the URL you're about to navigate to contains the /dashboard
path. If that's the case, then you should not schedule a new navigation and return true
instead.
map(() => {
// or
// this.userService.isLoggedIn() && !route.url.some(({ path }) => path === 'dashboard')
if (this.userService.isLoggedIn() && !state.url.includes('dashboard')) {
return this.router.createUrlTree(['/dashboard']);
}
return true;
}
推荐阅读
- c# - 我遇到关于“Expr1000”的错误
- reactjs - 在 ReactJS 中路由后从子组件获取值
- oracle - PL/SQL 异常未捕获异常
- android - 在两个顺序 addToBackStack 之后,supportFragmentManager.fragments 大小为 1
- unity3d - 如何统一导出带有mtl文件的obj文件?
- java - 方法参考中的错误返回类型:无法将 reactor.core.publisher.Mono 转换
为 reactor.core.publisher.Mono - node.js - VSCode 收集扩展错误 -4094 - 这是什么意思?
- r - summary_at 用于 R 中具有不同参数的多个变量和多个函数?
- amazon-web-services - 将 EBS 快照从一个区域复制到另一个区域
- java - Android 如何使用共享首选项检查用户登录或注销