I have an interceptor that adds a token in the headers. However, if I use it after a POST request my Observer in the subscription is not triggered.
Interceptor:
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
this.authService = this.inj.get(AuthService);
if (!this.authService.isLoggedIn()) {
return next.handle(req);
}
const changedReq = req.clone({headers: req.headers.set('Authorization', `Bearer ${this.authService.getToken()}`)});
return next.handle(changedReq);
}
Service:
saveBeer(beerForm: BeerForm): Observable<Response> {
let body = JSON.stringify(beerForm);
let headers = new HttpHeaders({
'Content-Type': 'application/json'
});
return this.http.post(this.apiUrl, body, {headers: headers});
}
Component:
onSubmitCreateBeer(): void {
this.beerService.saveBeer(this.beerForm)
.takeUntil(this.ngUnsubscribe)
.subscribe(
(response: Response) => {
// On response
this.router.navigate(['/beers']);
}, error => {
// On error
}, () => {
// On complete
});
}
My problem is that on response is never triggered so my navigation step doesn't work. If I disable the interceptor everything works.
Any ideas?
I got it working. The issue was that my observer was expecting json in the response. However, after i get 200 OK the response contains nothing in the body. That is an error, so the error function was called.
Solution 1 is to set responseType: text.
saveBeer(beerForm: BeerForm): Observable<any> {
let body = JSON.stringify(beerForm);
let headers = new HttpHeaders({
'Content-Type': 'application/json'
});
return this.http.post(this.apiUrl, body, {headers: headers, responseType: 'text'});
}
Solution 2 is to return 204 from the backend.
Both work fine for now. There is a bug report about that:
https://github.com/angular/angular/issues/18680
My workaround is an HttpInterceptor that catches errors when the status code is 200 and returns an HttpResponse with a null body instead (just like HttpClient does with 204 Not Content responses):
@Injectable()
export class EmptyResponseBodyErrorInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req)
.catch((err: HttpErrorResponse) => {
if (err.status == 200) {
const res = new HttpResponse({
body: null,
headers: err.headers,
status: err.status,
statusText: err.statusText,
url: err.url
});
return Observable.of(res);
} else {
return Observable.throw(err);
}
});
}
}
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