I can't find any way to inject my AuthService inside ErrorHandlerInterceptor. It returns me either an "undefined" object after injection, or it throws an error.
This is my ErrorHandlerInterceptor:
import { Injectable } from '@angular/core';
import { AuthService } from '@app/auth.service';
import { StorageService } from '@app/storage.service';
@Injectable({
providedIn: 'root'
})
export class ErrorHandlerInterceptor implements HttpInterceptor {
constructor(private authService: AuthService, private storageService: StorageService) {
console.log(this.authService); // undefined
}
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(error => this.errorHandler(error)));
}
// Customize the default error handler here if needed
private errorHandler(response: HttpErrorResponse): Observable<HttpEvent<any>>
{
// ... Various code
}
}
And this is my AuthService:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { StorageService } from './storage.service';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor(private _http: HttpClient,
private storageService: StorageService,
private router: Router) { }
}
I tried to list the service in the core.module.ts
providers, but errors are thrown:
ERROR RangeError: Maximum call stack size exceeded
at setCurrentInjector (core.js:1382)
at resolveNgModuleDep (core.js:8333)
at _createClass (core.js:8425)
at _createProviderInstance (core.js:8393)
at resolveNgModuleDep (core.js:8356)
at _createClass (core.js:8425)
at _createProviderInstance (core.js:8393)
at resolveNgModuleDep (core.js:8356)
at _createClass (core.js:8425)
at _createProviderInstance (core.js:8393)
Note that I am using the framework ngx-rocket
, created by ngx-rocket-generator
.
How can I do to fix this issue? Any advices?
UPDATE 1 -- CORE.MODULE.TS
Here is the core.module.ts file.
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from '@angular/common/http';
import { RouteReuseStrategy, RouterModule } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { ShellComponent } from './shell/shell.component';
import { HeaderComponent } from './shell/header/header.component';
import { RouteReusableStrategy } from './route-reusable-strategy';
import { AuthenticationService } from './authentication/authentication.service';
import { AuthenticationGuard } from './authentication/authentication.guard';
import { I18nService } from './i18n.service';
import { HttpService } from './http/http.service';
import { HttpCacheService } from './http/http-cache.service';
import { ApiPrefixInterceptor } from './http/api-prefix.interceptor';
import { ErrorHandlerInterceptor } from './http/error-handler.interceptor';
import { CacheInterceptor } from './http/cache.interceptor';
import { TokenInterceptor } from './http/token.interceptor';
import { StorageService } from '@app/storage.service';
import { AuthService } from '@app/auth.service';
@NgModule({
imports: [
CommonModule,
HttpClientModule,
TranslateModule,
NgbModule,
RouterModule
],
declarations: [
HeaderComponent,
ShellComponent
],
providers: [
AuthenticationService,
AuthenticationGuard,
I18nService,
HttpCacheService,
ApiPrefixInterceptor,
ErrorHandlerInterceptor,
CacheInterceptor,
TokenInterceptor,
{
provide: HttpClient,
useClass: HttpService
},
{
provide: RouteReuseStrategy,
useClass: RouteReusableStrategy
}
]
})
export class CoreModule {
constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
// Import guard
if (parentModule) {
throw new Error(`${parentModule} has already been loaded. Import Core module in the AppModule only.`);
}
}
}
Looks, like you have to add dependencies for your interceptor. In app.module.ts
instead of just edding to provide
section ErrorHandlerInterceptor
declare you provider in such way:
{
provide: HTTP_INTERCEPTORS,
useClass: ErrorHandlerInterceptor,
multi: true ,
deps: [AuthService, StorageService]
},
Be careful, the order of services in deps
should be the same, like in constructor.
PS. Not sure about Angular 6, but for Angular 8,9 it works perfectly.
Finally, I solved the problem. In the error handler, the dependencies cannot be injected through the constructor. To solve it, you need to do this:
First, import the Injector from @angular/core
and your service:
import { Injector } from '@angular/core';
import { AuthService } from '@app/auth.service';
Then, you have to inject it in the constructor:
constructor(private modalService: NgbModal, private injector: Injector) { }
And then you have to instantiate your service and use it like this:
const authService = this.injector.get(AuthService);
authService.logout();
The code, is going to be similiar to this:
import { Injector } from '@angular/core';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class ErrorHandlerInterceptor implements HttpInterceptor {
private authService: AuthService;
constructor(private modalService: NgbModal, private router: Router, private injector: Injector) { }
intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
return next.handle(request).pipe(catchError(error => this.errorHandler(error)));
}
// Customize the default error handler here if needed
private errorHandler(response: HttpErrorResponse): Observable<HttpEvent<any>> {
this.authService = this.injector.get(AuthService);
... Other code ...
}
Hope you have been helped by this answer!
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