angular - 如何在 Angular 服务中直接使用 .subscribe?
问题描述
解决了
我在 Angular 中实现用户的状态:isLogged true/false。
因此,无论我是哪个组件,我都会验证用户是否已登录以显示或隐藏内容。为此,我不想只控制 accessToken 是否在本地存储中,但我会使用 authService 检查它是否向服务器询问(使用 Http 请求)。所以我希望 authService 中的 isLogged() 只返回 true/false 或设置布尔值 true/false。通常我在组件的 .subscribe 中处理“res”和“err”,但我不会在每个组件中重复它。问题是我不知道如何在服务中直接使用 .subscribe 。
我正在使用此解决方案的那一刻。它有效,但我一点也不喜欢它!
isLogged() {
return this.http
.get<any>(this.isLoggedUrl)
.pipe(catchError(this.errorHandler));
}
// I call this method in each component that needs to know if user is logged
isLoggedResHandle() {
this.isLogged().subscribe(
(res) => {
if (res.status == 200) {
this.loggedIn = true;
}
},
(err) => {
if (err.error.message == 'TokenExpiredError') {
this.loggedIn = false;
//DO.. try refresh token. if refreshed: this.loggedIn = true
} else {
// for any other errors:
this.loggedIn = false;
}
}
);
}
解决方案
auth.service.ts
isLogged() {
const accessToken = this.getAccessToken;
if (typeof accessToken === 'undefined' || accessToken === null) {
console.log('pieroooooooooo');
this.loggedIn = false;
return;
}
return this.http
.get<any>(this.isLoggedUrl)
.pipe(catchError(this.errorHandler))
.subscribe(
(res) => {
if (res.status == 200) {
this.loggedIn = true;
}
},
(err) => {
if (err.error.message == 'TokenExpiredError') {
const refreshToken = this.getRefreshToken;
if (typeof refreshToken !== 'undefined' || refreshToken !== null) {
this.loggedIn = false;
}
this.loggedIn = false;
// TODO: try to refresh it
} else {
this.loggedIn = false;
}
}
);
}
getIsLogged() {
return this.loggedIn;
}
header.component.ts 或我想要的任何组件,例如:
<button class="btn btn-light my-2 my-sm-0" id="cartBtn" *ngIf="authService.getIsLogged()" [routerLink]="'/profile'"
type="submit">
<i class="fas fa-shopping-cart"></i>
Mio Profilo
</button>
app.component.ts // 在刷新后保持“用户状态”更新:
export class AppComponent implements OnInit {
constructor(private authService: AuthService) {}
ngOnInit(): void {
this.authService.isLogged();
}
}
解决方案
解决方案可以是ParentComponentClass
实现isLoggedResHandle
逻辑的解决方案,并且每个需要它的组件都可以扩展类。
class ParentWithIsLoggedLogicCompoent {
loggedIn = false
constructor(private isLogged: IsLoggedService) {}
isLoggedResHandle() {
this.isLogged().subscribe(
isLogged => this.loggedIn = isLogged,
error => this.loggedIn = false
)
}
}
class YourOtherComponent extends ParentWithIsLoggedLogicCompoent implements OnInit {
ngOnInit() {
this.isLoggedResHandle();
}
}
您可以使用运算符将重试逻辑提取到服务中retryWhen
。我不确定语法是否良好,但它会是这样的:
isLogged() {
return this.http
.get<any>(this.isLoggedUrl)
.pipe(
retryWhen(errors => {
errors.switchMap(error => {
if(errors.error.message != 'TokenExpiredError') {
throw errors
}
//DO.. try refresh token. if refreshed: this.loggedIn = true
})
}),
catchError(this.errorHandler)
);
}
推荐阅读
- indexing - 多个辅助本地索引列上的 Apache phoenix 问题
- python - 在python中将json数据转换为pandas数据框(列表内的字典)
- google-sheets - 谷歌表格数组公式列结果乘以单元格值
- python - 在 pandas 列中替换为 Python 正则表达式
- c# - 持久字典
无法为自定义结构创建 - html - css 图像/图像:后和背景颜色
- python - 如何检查python中的路径是否是文件?
- ios - Alamofire 堆叠响应
- docker - 在 docker 容器中使用 nginx certbot 时证书无效
- python - 不支持 img 数据类型 = 17