我为HTTP请求添加了一个拦截器,在这里我必须使用用户实例的访问令牌。在我的应用程序组件中,我初始化了用户:
app.component.ts
private async restoreUser(): Promise<UserModel | any> {
// ... some view stuff
return this.userService.restore()
// login instance could be found
.then(async () => {
// ... some view stuff
})
// local storage is empty -> login is necessary
.catch(async () => {
// ... some view stuff
this.subscription = this.networkSrv.getNetworkStatus()
.subscribe((status: ConnectionStatus) => {
if (status === ConnectionStatus.Online) {
// ... some view stuff
} else {
// ... some view stuff
}
});
});
}
http.interceptor.ts
return this.userSrv.user.pipe(
map((user: UserModel) => request.clone(
{setParams: {'access-token': user.accessToken}}
)),
mergeMap(request => next.handle(request))
);
现在,我想通过初始化我的应用程序来发出请求。问题是,用户实例为空,应用程序引发错误。有没有办法像await
->这样来设置用户实例?
示例:
this.transmissionSrv.restoreQueue().then((projects: ProjectModel[]) => {
this.transmissionSrv.transmitProjects(projects, true).subscribe(console.log);
});
当前,我使用setTimeout
方法,但这不是我应该这样做的方法,对吗?另外,对使用Observer不一致表示抱歉;离子经常使用Promises(?)
答案 0 :(得分:1)
您应该尝试在地图之前添加过滤器。使用过滤器,您的地图只有在设置了用户之后才会被呼叫。
return this.userSrv.user.pipe(
filter(Boolean),
map((user: UserModel) => request.clone(
{setParams: {'access-token': user.accessToken}}
)),
mergeMap(request => next.handle(request))
);
答案 1 :(得分:1)
有两种方法可以解决此问题。
APP_INITIALIZER
(请参阅here)进行后端调用,并确保在应用程序引导时存在用户对象。BehaviorSubject
中,并使依赖它的组件在需要用户实例的任何地方订阅该BehaviorSubject
。服务构造完成后,让它进行后端调用,并在完成后将完成的用户实例粘贴在BehaviorSubject
(userSubject.next(user)
)中。