I am having an HTTP Interceptor. The backend API expects custom headers whose values are stored in indexdb during app initialization and other operations. Hence, I need to get the values and pass it with every request. But so far, failing to do so as the interceptor does not wait for the subscription to finish executing and sends requests without the custom headers.
The intercetpor does get the currently saved or default headers but it is too late as the request goes thru without the headers.
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);
}
}
The intercept function just needs to return an observable. So you start be making a request to the currentConfig()
and then switch to the next interceptor when the config is emitted.
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);
})
);
}
you can use mergeMap to create async interceptor
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);
})
);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With