I'm using HttpInterceptor
api of new Angular HttpClientModule
and now stuck with a situation. Here is my use-case.
In my application, if any service makes an http call, I want to make another silent http call before it, and want to store it's result locally. Once the silent call is completed, then only I'll proceed with the service's http call and will return its result.
Here is what I'm doing. (Using HttpInterceptor)
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (req.url.match(/api\//)) { // api call
http.post('/auth/silentCall', {user: 123}).subscribe(
(data) => {
console.log(data);
const clone = req.clone({ setHeaders: { 'Authorization ': tokenService.getToken() } });
return next.handle(clone).do((event: HttpEvent<any>) => {
if (event instanceof HttpResponse) {
console.log('Service's call response');
}
}, (err: any) => {
if (err instanceof HttpErrorResponse) {
console.log('Network call err', err);
}
});
},
(err) => {
if (err instanceof HttpErrorResponse) {
return Observable.throw(err);
}
);
} else {
console.log('Not an api call..It's an auth call');
return next.handle(req); // call original auth request.
}
}
Now, problem with the above code is, it is executing internal silent call successfully, but never calls the original api call after that. So the service keeps waiting forever.
Updated: Added a working plunkr. https://plnkr.co/edit/WFecj8fFZ6z4G6mpLSCr?p=preview
Take note of the sequence that the calls are being made and the headers that are being added using your browser's dev tools.
Also note that the below solution is using RxJS lettable operators instead of the standard operators (which shouldn't have any different behavior... adding this note in case the code doesn't compile)
The cause of the problem is the fact that the
intercept
method is never returning a handle in the case that the call matches/api
.Update your code to something similar to the following
Note that the response of the
http.post
is being flatmaped to return the observable sequence returned by thenext.handle()
method or to thrown a terminated observable withObservable.throw()
.Also note that the if condition has been removed since if the api call fails, the catch block is called (or the error handler function, in case of subscribe)
You are not returning the
observable
insideif
. Try this