我有一个HTTP拦截器。后端API需要自定义标头,其值在应用程序初始化和其他操作期间存储在indexdb中。因此,我需要获取值并将其随每个请求传递。但是到目前为止,由于拦截器没有等待订阅完成执行并发送没有自定义标头的请求,因此未能这样做。
intercetpor确实获得了当前保存的或默认的标头,但为时已晚,因为没有标头的请求通过了。
indexdb.service.ts:
@Injectable()
export class IndexDBService {
/*
Handles configuration of the app:
reading current configuration
saving configuration
*/
private pouch: any;
constructor() {
this.pouch = new PouchDB("config", {
auto_compaction: true
});
}
currentConfig(): Observable<any> {
/*
Return the current configuration saved in the database
*/
let vm = this;
return new Observable(observer => {
vm.pouch.get("info", function(err, doc) {
if (err) {
console.log("config read error ", err);
// create a default one
configOptions={'header1': '1','header2':2}
observer.next(configOptions);
} else {
observer.next(doc);
}
});
});
}
}
interceptor.ts
import { Injectable } from "@angular/core";
import {
HttpEvent,
HttpInterceptor,
HttpHandler,
HttpRequest,
HttpHeaders
} from "@angular/common/http";
import { Observable } from "rxjs";
import { IndexDBService } from "../services/indexdb.service";
@Injectable()
export class InterceptAPICalls implements HttpInterceptor {
constructor(private indexdbService: IndexDBService) {}
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
this.indexdbService.currentConfig().subscribe(configData => {
console.log(configData); // ==> does work great. I am getting data right
req = req.clone({
headers: new HttpHeaders({
"X-Header1": configData["header1"],
"X-Header2": configData["header2"]
})
});
return next.handle(req); // want this one to return always
});
// below is cos the app won't compile and it returns immediately
return next.handle(req);
}
}
答案 0 :(得分:3)
您可以使用 mergeMap 创建异步拦截器
intercept(
req: HttpRequest<any>,
next: HttpHandler
): Observable<HttpEvent<any>> {
return this.indexdbService.currentConfig().pipe(mergeMap(configData => {
console.log(configData); // ==> does work great. I am getting data right
req = req.clone({
headers: new HttpHeaders({
"X-Header1": configData["header1"],
"X-Header2": configData["header2"]
});
});
return next.handle(req);
})
);
}
答案 1 :(得分:1)
拦截函数只需要返回一个可观察值。因此,您开始向currentConfig()
发出请求,然后在发出配置时切换到下一个拦截器。
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return this.indexdbService
.currentConfig()
.pipe(
first(),
mergeMap(configData => {
req = req.clone({
headers: new HttpHeaders({
'X-Header1': configData['header1'],
'X-Header2': configData['header2']
})
});
return next.handle(req);
})
);
}