pjlamb12
pjlamb12

Reputation: 2422

Inject Instance of Service into Another Service

I have an interceptor service that intercepts each request, attaches a token, and then continues on. I have a catch function declared to catch each error and check the status. If it's a 401 or 403, I want to redirect to the login page. Here's the code:

export class TokenInterceptorService implements HttpInterceptor {
    private _oidc: OidcSecurityService;
    private _router: Router;

    constructor(private injector: Injector) {}

    private handleAuthError(err: HttpErrorResponse): Observable<any> {
        if (this._router === undefined) {
            this._router = this.injector.get(Router);
        }
        if (err.status === 401 || err.status === 403) {
            this._router.navigate(['/auth/login']);
            return Observable.throw(err.message);
        }
        return Observable.throw(err);
    }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        let newRequest = request;

        if (this._oidc === undefined) {
            this._oidc = this.injector.get(OidcSecurityService);
        }

        if (this._oidc !== undefined) {
            const token = this._oidc.getToken();
            if (token !== '') {
                newRequest = request.clone({
                    setHeaders: {
                        Authorization: `Bearer ${token}`,
                    },
                });
            }
        }

        return next.handle(newRequest).catch(this.handleAuthError);
    }
}

The issue is that in the handleAuthError function, this.injector is undefined, so I can't inject a reference to the Router service. The weird thing though is that in the intercept method, this.injector is defined and gets a reference to the OidcSecurityService

I also tried putting the handleAuthErrorcode inline in a callback from the intercept method, but I got the same error.

Here's a screenshot of the error while debugging in VS Code.

TypeError: Cannot read property 'get' of undefined. ERROR

I'm not sure how to make sure that the injector is present and available so that I can handle that error properly.

Here's the declaration in the app.module:

{
    provide: HTTP_INTERCEPTORS,
    useClass: TokenInterceptorService,
    multi: true,
},

Upvotes: 1

Views: 96

Answers (1)

Oleksandr Poshtaruk
Oleksandr Poshtaruk

Reputation: 2146

Try to change this line:

return next.handle(newRequest).catch(this.handleAuthError);

to

return next.handle(newRequest).catch((err) => this.handleAuthError(err));

to bind context(class instance).

Upvotes: 2

Related Questions