Angular 6 enters infinite loop of cyclic dependency when I inject a service that uses HttpClient inside my HttpInterceptor class
Asked Answered
S

1

6

I have found this issue many times in different Angular versions but multiple sources say it is already fixed, for example, another similar question on Stackoverflow is having this answer which says that it was solved in Angular 5.2 , some other issues on Github are saying it solved in 6.0.2 , I am using Angular 6.0.3 but still I get that issue, whenever I try injecting a service that uses HttpClient inside my HttpInterceptor class (that should add a jwt token to the requests if the jwt was received in that service)

I don't get a warning or error that I have cyclic dependency, put I can see in the browser console thousands of requests that the Interceptor is calling the service & vice-versa.

What is the proper way to handle this issue? (preferably without storing jwt in localstorage)

(i.e using the interceptor & getting the jwt from the service)

My service:

 ....
 // only showing parts that matter, HttpClient is injected here
 // to be used in calling the API services

  constructor(public http: HttpClient, private route: ActivatedRoute,
 public translate: TranslateService, private router: Router,
 public snackBar: MatSnackBar, private notification: NotificationService) {

//

My HttpInterceptor:

import { Observable } from 'rxjs';
import { Location } from '@angular/common';
import { Injectable, Injector } from '@angular/core';
import { HttpInterceptor } from '@angular/common/http';
import { HttpRequest } from '@angular/common/http';
import { HttpHandler } from '@angular/common/http';
import { HttpEvent } from '@angular/common/http';
import { HttpHeaders } from '@angular/common/http';
import { DataService } from './data/data.service';

@Injectable()
export class CustomHttpInterceptor implements HttpInterceptor {
  constructor(private injector: Injector) {}

intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
  const dataService = this.injector.get(DataService);

  console.log('hey there, we are here INTERCEPTOR');
  if (dataService.jwt) {
        request = request.clone({
          setHeaders: {
            Authorization: `Bearer ${dataService.jwt}`
          }
        });
      }

    return next.handle(request);
  }
}

ng version

Angular CLI: 6.0.8
Node: 10.0.0
OS: win32 x64
Angular: 6.0.7
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.6.3
@angular-devkit/build-angular     0.6.3
@angular-devkit/build-optimizer   0.6.3
@angular-devkit/core              0.6.3
@angular-devkit/schematics        0.6.8
@angular/cdk                      6.1.0
@angular/cli                      6.0.8
@angular/flex-layout              6.0.0-beta.15
@angular/material                 6.3.1
@ngtools/webpack                  6.0.3
@schematics/angular               0.6.8
@schematics/update                0.6.8
rxjs                              6.2.1
typescript                        2.7.2
webpack                           4.8.3
Saleswoman answered 2/7, 2018 at 18:0 Comment(0)
S
0

I was able to work around it by instantiating HttpClient myself inside the service:

@Injectable()
export class DataService {

  private http: HttpClient;

  constructor(httpBackend: HttpBackend) {
    this.http = new HttpClient(httpBackend);    
  }
}

This broke the infinite loop issue in my case (using [email protected]).

Speer answered 17/10, 2018 at 13:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.