[英]Angular: wait for the return of one observable to initiate the other
我的业务场景是这样的:我首先向WebAPI中的token()端点发出HTTP请求以获取auth令牌(这发生在app.component.ts中)。 然后,我有一个令牌拦截器模块,将令牌附加到后续请求的HTTP标头中。
然后,我在WebAPI中有一个getLanguages()端点,并且在我的标头组件header.component.ts中调用了该端点。 因此,此调用通过HTTP侦听器,尝试将生成的令牌附加到请求标头,但是由于token()端点尚未返回,因此失败,因此getLanguages()端点未通过身份验证。
我显然在这里错过了一些东西。 我读过有关ReplaySubject
但不确定如何将所有内容放在一起。
这是我当前的代码。
<app-header>
</app-header>
<router-outlet></router-outlet>
<app-footer>
</app-footer>
authenticateClient(){
let body = new HttpParams()
.set('client_id', AppConst.GLOBAL.auth.client_id)
.set('grant_type', AppConst.GLOBAL.auth.grant_type)
.set('scope', AppConst.GLOBAL.auth.scope);
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded'
})
};
let authGatewayUrl: string = AppConst.GLOBAL.authApiUrl + window.location.search;
return this.http.post(authGatewayUrl, body.toString(), httpOptions)
.pipe(map((res: any) => this.token = res), catchError(this.handleErrorObservable));
}
getToken(): Token {
return this.token;
}
token: Token;
ngOnInit() {
// get the authentication token and store it for usage in subsequent API calls.
this.authService.authenticateClient().subscribe(
obj => this.token = obj as Token,
err => alert(err)
);
}
getLanguages() {
return this.http.get(this.localeApiUrl)
.pipe(map((res: any) => this.languages = res), catchError(this.handleErrorObservable));
}
constructor(private appService: AppService) {
this.appService.getLanguages().subscribe(obj => this.languages = obj);
};
intercept(req: HttpRequest<any>, next: HttpHandler) {
// exclude the token API endpoint from the interception
const loginUrl: string = AppConst.GLOBAL.authApiUrl;
if (req.url.search(loginUrl) === -1) {
// Get the auth token from the service.
const authToken = this.auth.getToken();
//// Clone the request and set the new header in one step.
req = req.clone({ setHeaders: { Authorization: authToken.access_token } });
}
//// send cloned request with header to the next handler.
return next.handle(req);
}
你可以节省您的令牌信息在BehaviorSubject
的AuthService内。
然后在authenticateClient()
成功时触发.next(token)
。
在header.component
,您可以这样做。
readonly languages$ = this.authService.token$.pipe(
first(!!token), // or filter, depends on your application logic
switchMap(() => this.appService.getLanguages(),
);
this.languages$.subscribe(obj => this.languages = obj);
在上面的代码中,您将从authService创建一个新的Observable,当有人在令牌BehaviorSubject
上触发next
一个触发时,该Observable将检查是否已定义令牌,如果已定义,则可以调用内部API。
这是一种方法,但是我认为还有其他解决方案。
您可以使用Promise。
var promise = new Promise((resolve, reject) => {
setTimeout(() => {
console.log("Async Work Complete");
if (error) {
reject();
} else {
resolve();
}
}, 1000);
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.