【问题标题】:Angular RouteGuard "A function whose declared type is neither 'void' nor 'any' must return a value"Angular RouteGuard“声明类型既不是'void'也不是'any'的函数必须返回一个值”
【发布时间】:2021-12-01 16:13:42
【问题描述】:

我有一个路由守卫,可以在继续之前检查用户是否有权访问资源。订阅后,我检查用户是否有访问权限,如果没有,则使用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);
  }

【问题讨论】:

标签: angular rxjs canactivate angular-route-guards


【解决方案1】:

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

解决方案:

  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;
      }
    });
  }
}

【讨论】:

  • 我得到 'Observable' 类型的参数不可分配给'OperatorFunction' 类型的参数。类型 'Observable' 提供不匹配的签名 '(来源:Observable):Observable'
【解决方案2】:

我会尝试在函数中返回 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;
      }
    })
  )
}

【讨论】:

  • 这似乎也不起作用,仍然出现语法错误。
  • 另一个?
猜你喜欢
  • 1970-01-01
  • 2018-03-18
  • 2018-03-09
  • 2019-01-06
  • 1970-01-01
  • 1970-01-01
  • 2017-06-12
  • 2018-03-15
  • 1970-01-01
相关资源
最近更新 更多