I recently upgraded our application from angular 2 to angular 5 and also made the switch from the deprecated Http module to the new HttpClient.
In the previous version of the application, I used the Http-Client to redirect to a specific page in case of errors.
import {Router} from "@angular/router";
import {Injectable} from "@angular/core";
import {ConnectionBackend, Http, Request, RequestOptions, RequestOptionsArgs, Response} from "@angular/http";
import {Observable} from "rxjs/Observable";
import "rxjs/add/operator/catch";
@Injectable()
export class HttpService extends Http {
constructor(backend: ConnectionBackend, defaultOptions: RequestOptions, private router: Router) {
super(backend, defaultOptions);
}
request(url: string | Request, options?: RequestOptionsArgs): Observable<Response> {
return super.request(url, options)
.catch(this.catchErrors());
}
private catchErrors() {
return (res: Response) => {
if (this.isError(res)) {
console.log(`Internal server error occurred (${res.status} - ${res.statusText})`);
this.router.navigateByUrl('/error');
} else if (this.isUnauthorized(res)) {
console.log(`User is not authenticated - either not logged in or session expired (${res.status} - ${res.statusText})`);
this.router.navigateByUrl('/logout');
} else if (this.isForbidden(res)) {
console.log(`User does not have necessary permissions for the resource (${res.status} - ${res.statusText}): ${res.url}`);
this.router.navigateByUrl('/forbidden');
}
return Observable.throw(res);
};
}
private isError(res: Response): boolean {
return res && res.status === 500;
}
private isUnauthorized(res: Response): boolean {
return res && res.status === 401;
}
private isForbidden(res: Response): boolean {
return res && res.status === 403;
}
}
After the upgrade, I have refactored this functionality to use an HttpInterceptor instead.
import {Router} from "@angular/router";
import {Injectable} from "@angular/core";
import {Observable} from "rxjs/Observable";
import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse} from "@angular/common/http";
@Injectable()
export class HttpService implements HttpInterceptor {
constructor(private router: Router) {
}
private catchErrors() {
return (res: HttpResponse<any>) => {
if (this.isError(res)) {
console.log(`Internal server error occurred (${res.status} - ${res.statusText})`);
this.router.navigateByUrl('/error');
} else if (this.isUnauthorized(res)) {
console.log(`User is not authenticated - either not logged in or session expired (${res.status} - ${res.statusText})`);
this.router.navigateByUrl('/logout');
} else if (this.isForbidden(res)) {
console.log(`User does not have necessary permissions for the resource (${res.status} - ${res.statusText}): ${res.url}`);
this.router.navigateByUrl('/forbidden');
}
return Observable.throw(res);
};
}
private isError(res: HttpResponse<any>): boolean {
return res && res.status === 500;
}
private isUnauthorized(res: HttpResponse<any>): boolean {
return res && res.status === 401;
}
private isForbidden(res: HttpResponse<any>): boolean {
return res && res.status === 403;
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(req).catch(this.catchErrors());
}
}
However, after implementing this change, the navigateByUrl method seems to have no effect and the site remains accessible even after encountering errors.
Any suggestions on how to address this issue would be greatly appreciated.