我正在编写使用IndexedDB缓存数据的Angular应用程序。
每当应用程序即将对服务器进行特定的http调用时 我想从IndexedDB中检索这些数据,并从服务器中丰富或替换响应。
问题是从IndexedDB检索数据是异步操作,它返回Observable,我无法将修改后的数据返回给调用服务。
拦截器看起来像这样:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).map((event) => {
if (event instanceof HttpResponse) {
console.log("before cacheResponseProccess");
const val: Observable<HttpEvent<any>> = this.angularCache.cacheResponseProccess(event);
val.subscribe(x => {
console.log('Return modified response is:');
console.log(x);
return x;
});
}
}).catch((error, caught) => {
return Observable.throw(error);
});
}
查看问题示例
答案 0 :(得分:3)
你需要在map
运算符中返回一些东西(在异步的回调函数中返回值,并且真正将它们返回到外部函数)。此外,当您检索异步结果以替换原始HttpResponse时,您可以将map
更改为mergeMap
运算符并在其中返回Observable。
尝试使用以下代码示例:
return next.handle(req).mergeMap((event) => { // use mergeMap instead of map
return new Observable(ob => { // return new Observable to retrieve asynchronous data
if (event instanceof HttpResponse) {
console.log("before cacheResponseProccess");
const val: Observable<HttpEvent<any>> = this.angularCache.cacheResponseProccess(event);
val.subscribe(x => {
console.log('Return modified response is:', x);
ob.next(x); // return modified result
});
}
});
}).catch((error, caught) => {
return Observable.throw(error);
});
修正 demo 。
答案 1 :(得分:0)
您可以执行以下操作:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.indexOf('https://api.someurl.com/') > -1) {
let authReq: HttpRequest<any> = req;
return this.authService.getCurrentSession().pipe(
mergeMap(
(session: Session) => {
const token: string = session.getToken();
authReq = req.clone({
headers: req.headers.set('Authorization', token)
});
return next.handle(authReq);
}
),
catchError(
(error) => {
console.error('Intercept error, couldn\'t add authorisation headers', error.message);
next.handle(authReq);
return of(error);
}
)
);
} else {
return next.handle(req);
}
}