Angular RouteGuard "A function whose declared type is neither 'void' nor 'any' must return a val



我有一个路由保护,在继续之前检查用户是否有访问资源的权限。订阅后,检查用户是否具有访问权限,如果没有,则使用parseUrl重定向或返回true

@Injectable({ providedIn: 'root' })
export class PortfolioGuard implements CanActivate {
constructor(private resourceAccessService: ResourceAccessService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean | UrlTree {
const id = +route.paramMap.get('id');
// return this.resourceAccessService.checkUserAccessToPortfolio(id);
this.resourceAccessService.checkUserAccessToPortfolio(id).subscribe((hasAccess) => {
if (!hasAccess) {
console.log('No access');
return this.router.parseUrl('/');
} else {
console.log('access');
return true;
}
});
}
}

如果我只返回支票,这可以工作,但我也希望它根据该支票进行重定向。

@Injectable({ providedIn: 'root' })
export class PortfolioGuard implements CanActivate {
constructor(private resourceAccessService: ResourceAccessService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
const id = +route.paramMap.get('id');
return this.resourceAccessService.checkUserAccessToPortfolio(id);
}
}

我在第一个代码块中遗漏了什么,我应该从服务中解析订阅…

checkUserAccessToPortfolio(id: number): Observable<boolean>  {
const url = this.baseUrl + this.userResourceAccessUrl + '/' + + id + '/portfolio';
return this.http.get<boolean>(url);
}

我会尝试在函数中返回Observable:

canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean | UrlTree {
const id = +route.paramMap.get('id');

return this.resourceAccessService.checkUserAccessToPortfolio(id).pipe(
map(hasAccess => {
if (!hasAccess) {
console.log('No access');
this.router.parseUrl('/');
return false
} else {
console.log('access');
return true;
}
})
)
}

这个问题很明显。您的函数中没有返回任何内容。

解决方案:

  1. 添加返回到您的函数canActivate
  2. 删除订阅并将所有逻辑移动到映射操作符。也可以使用tapswitchMap运算符。这取决于你的环境。

不这样做:

@Injectable({ providedIn: 'root' })
export class PortfolioGuard implements CanActivate {
constructor(private resourceAccessService: ResourceAccessService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean | UrlTree {
const id = +route.paramMap.get('id');
// return this.resourceAccessService.checkUserAccessToPortfolio(id);
this.resourceAccessService.checkUserAccessToPortfolio(id).subscribe((hasAccess) => {
if (!hasAccess) {
console.log('No access');
return this.router.parseUrl('/');
} else {
console.log('access');
return true;
}
});
}
}

您可以尝试使用pipemap运算符。

@Injectable({ providedIn: 'root' })
export class PortfolioGuard implements CanActivate {
constructor(private resourceAccessService: ResourceAccessService, private router: Router) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean | UrlTree {
const id = +route.paramMap.get('id');
return this.resourceAccessService.checkUserAccessToPortfolio(id).pipe( map( hasAccess => {
if(!hasAccess) {
console.log('No access');
this.router.parseUrl('/');
return false
} else {
console.log('access');
return true;
}
});
}
}

相关内容

最新更新