1

I get this error:
Provider parse errors: Cannot instantiate cyclic dependency!

I have a Component to make http calls to my backend:
backend.component.ts

import { HttpClient } from '@angular/common/http';
public basicQuery(): void {
  this.httpClient.get('http://...')
    .subscribe(
    (response) => {

    },
    error => {

    });
}

I use interceptor for every call.
token.interceptor.ts

public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  request = request.clone({
    setHeaders: {
      token: this.auth.getToken()
    }
  });

  return next
    .handle(request)
    .do(
    (response: HttpEvent<any>) => {
    },
    (error: any) => {
      return false;
  });
}

If i get an error, i handle this in my custom error handler because i want to send the error to my backend.
custom-error-handler.ts

handleError(error): void {
  this.errorLogService.logServer(error);
  super.handleError(error);
}

Therefor i use a service.
errorLog.service.ts

import { HttpClient } from '@angular/common/http';
logServer(error: Error) {
  this.httpClient.post('http://...', JSON.stringify(error.message))
    .subscribe(
    (response) => { },
    (error) => { });
}

And here is the problem, because i use also the httpClient. But how can i avoid this failure, how do it right? Right now i use 'Http' instead of 'HttpClient'.

Update 1

private auth: AuthService;

constructor(
  private utils: Utils,
  private router: Router,
  private injector: Injector
) {
  this.auth = this.injector.get(AuthService);
}

public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  request = request.clone({
    setHeaders: {
      token: this.auth.getToken()
    }
  });

  return next
    .handle(request)
    .do(
      (response: HttpEvent<any>) => { },
      (error: any) => { return false }
    );
}

Update 2

Injecting the AuthService and Router into the body fixes the problem:

public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  const started = Date.now();

  this.auth = this.injector.get(AuthService);
  this.router = this.injector.get(Router);

  (...)
}
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
HansDampfHH
  • 575
  • 1
  • 4
  • 10
  • So are you getting this in your interceptor? I have faced a same error in interceptor constructor, if yes I may have an answer for you. – Deepak Jha Dec 12 '17 at 11:00

1 Answers1

2

Here is how you could do this, Do not inject the service in the constructor instead do that in your function body. Here you would also not run into the issues like maximum call reached.

@Injectable()
export class YourInterceptor implements HttpInterceptor {
  yourService: YourService;
  constructor(private inject: Injector) {
    //this.yourService = inject.get(YourService);
  }

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {

    this.yourService = this.inject.get(YourService);

    request = request.clone({
       setHeaders: {
          token: this.YourService.getToken()
       }
    });

    return next.handle(request);    
  }
}

As per your constructor try this,

private auth: AuthService;
private router: Router;

constructor(
  private utils: Utils,
  private injector: Injector
) {

}

public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  this.router = this.injector.get(Router);
  this.auth = this.injector.get(AuthService);
  request = request.clone({
    setHeaders: {
      token: this.auth.getToken()
    }
  });

  return next
    .handle(request)
    .do(
      (response: HttpEvent<any>) => { },
      (error: any) => { return false }
    );
}
Deepak Jha
  • 1,539
  • 12
  • 17
  • This does not work either -> RangeError: Maximum call stack size exceeded – HansDampfHH Dec 12 '17 at 13:42
  • Can you please show your constructor code? That you have written for interceptor – Deepak Jha Dec 12 '17 at 13:53
  • Updated, but i thought it was comming out of the error.service because there i also import httpClient and not from the interceptor. – HansDampfHH Dec 12 '17 at 14:33
  • then how come you got maximum call exceeded after that change? I am updating my answer try that and let me know if that works I believe it will because in constructor you have given the service injection which i believe is faulty or not proper. I believe my commented codes in constructor confused you a little, those are commented because I ran into same problem of max stack size if i un-comment. :) – Deepak Jha Dec 12 '17 at 14:49
  • Sorry, does not work. I inject now the auth.service in intercept(). Provider parse errors: Cannot instantiate cyclic dependency! Router ("[ERROR ->]") – HansDampfHH Dec 12 '17 at 15:24
  • Is it really emanating from your interceptor? You said after change to injector.get you got max call error, now you are back to your first error? That is strange, you should not get that error after you inject.get in your interceptor code make sure you remove injector.get from constructor – Deepak Jha Dec 12 '17 at 15:33
  • Can you please send me the git hub of your codes let me see if I can help – Deepak Jha Dec 12 '17 at 15:44
  • try putting the Router also in the interceptor body, I see this was also causing the cyclic dependency error. – Deepak Jha Dec 13 '17 at 06:46
  • Perfect, that was the failure. I put the Router also in the body. Errors are gone.Thank you very much for yout help ! – HansDampfHH Dec 13 '17 at 11:00
  • ahh finally :) I had changed my answer you can perhaps accept that as a solution. – Deepak Jha Dec 13 '17 at 11:03