我正在用angular 8应用程序编写属性,以检查服务的可用性。该属性调用观察对象进行检查,并返回true或false。 我试图在我的身份验证保护服务中调用此属性。我面临的问题是,当第一次调用该属性时,它返回未定义的值,后来我看到正在执行的订阅中的代码。在执行该属性的if块检查时,它已经不确定,因此不会执行 我该如何处理?
我要实现的目的是通过检查TE服务是否可用将用户从auth Guard自身重定向到脱机页面。有人可以告诉我问题出在哪里吗
我在auth Guard服务中添加的条件块是
if (!isServiceAvailable) {
this.router.navigate(['/offline'])
return false
}
授权保护服务
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {
constructor(
private authService: AuthService,
private router: Router,
private alertService: AlertService,
private connectionService: ConnectionService
) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let url: string = state.url
return this.checkLogin(url)
}
canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
return this.canActivate(route, state)
}
canLoad(route: Route): boolean {
let url = `/${route.path}`
return this.checkLogin(url)
}
checkLogin(url: string): boolean {
let isLoggedIn = this.authService.isLoggedIn
let isSessionExpired = this.authService.isSessionExpired
let isServiceAvailable = this.connectionService.isApiAvailable
if (!isServiceAvailable) {
this.router.navigate(['/offline'])
return false
}
// user is logged in and session didn't expire
if (isLoggedIn && !isSessionExpired) {
return true
}
if (isLoggedIn && isSessionExpired) {
this.authService.refreshLogin().subscribe()
return true
}
// redirect and logout
this.authService.loginRedirectUrl = url
this.router.navigate(['/login'])
this.authService.logout(isLoggedIn && isSessionExpired)
return false
}
}
连接服务
@Injectable()
export class ConnectionService {
constructor(
private httpClient: HttpClient,
private configurationService: ConfigurationService
) {
const source = timer(0, Number(environment.corePingIntervalSeconds) * 1000)
source.subscribe(() => {
this.checkIfCoreApiIsAvailable()
.pipe(first())
.subscribe(
resp => {
// if (resp.status === 200 ) {
// // console.log(true)
// } else {
// // console.log(false)
// }
},
err => console.log(err)
)
})
}
get isApiAvailable(): boolean {
let isAvailable: boolean
this.checkIfCoreApiIsAvailable()
.pipe(first())
.subscribe(
resp => {
if (resp.status === 200) {
isAvailable = true
} else {
isAvailable = false
}
},
err => console.log(err)
)
return isAvailable
}
checkIfCoreApiIsAvailable() {
var pingUrl = this.configurationService.baseUrl + '/api/online'
return this.httpClient.get(pingUrl, {
observe: 'response'
})
}
}
答案 0 :(得分:0)
您将在观察值完成之前返回isAvailable
。您需要对其进行更改,以便函数返回可观察到的值:
get isApiAvailable(): Promise<boolean> {
return this.checkIfCoreApiIsAvailable()
.pipe(
first(),
map(resp => {
if (resp.status === 200 ) {
return true;
}
return false;
})
)
.toPromise();
}
然后您需要在此处处理可观察到的响应:
let isServiceAvailable = await this.connectionService.isApiAvailable;
请注意我如何将可观察的对象转换为一个Promise,以便您可以使用await
而不必更改太多代码。确保在checkLogin
函数前面加上async
关键字,否则使用await
会引发错误。
如果您不想使用Promise,则可以简单地调整代码以监听可观察到的响应。