title: Getting a cyclic dependency error
body: <p>I'm trying to make use of the <a href="https://github.com/auth0/angular2-jwt" rel="nofollow noreferrer">angular-jwt</a> but I get the follower cyclic dependency error:</p>
  
  <pre><code>Cannot instantiate cyclic dependency! InjectionToken_JWT_OPTIONS
    at NgModuleProviderAnalyzer.parse (compiler.js:19550)
      at NgModuleCompiler.compile (compiler.js:20139)
      at JitCompiler._compileModule (compiler.js:34437)
      at eval (compiler.js:34368)
      at Object.then (compiler.js:474)
      at JitCompiler._compileModuleAndComponents (compiler.js:34366)
      at JitCompiler.compileModuleAsync (compiler.js:34260)
      at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:239)
      at PlatformRef.bootstrapModule (core.js:5567)
      at eval (main.ts:13)
  </code></pre>
  
  <p>In my first demo Angular 5 application, here is my setup:</p>
  
  <pre><code>import {NgModule} from '@angular/core';
  import {HttpClientModule} from '@angular/common/http';
  import {JwtModule, JWT_OPTIONS} from '@auth0/angular-jwt';
  
  import {KeycloakService} from './keycloak.service';
  
  // See https://github.com/auth0/angular2-jwt
  
  export function jwtOptionsFactory(keycloakService) {
    return {
      whitelistedDomains: ['localhost:3001'],
      blacklistedRoutes: ['localhost:3001/auth/'],
      tokenGetter: () =&gt; {
        return keycloakService.getJwtTokenFromLocalStorage();
      }
    };
  }
  
  @NgModule({
    imports: [
      HttpClientModule,
      JwtModule.forRoot({
        jwtOptionsProvider: {
          provide: JWT_OPTIONS,
          useFactory: jwtOptionsFactory,
          deps: [KeycloakService]
        }
      })
    ],
    providers: [
      KeycloakService
    ]
  })
  export class AuthModule {}
  </code></pre>
  
  <p>Having an empty deps: property removes the issue. Of course, no service being injected is no solution either.</p>
  
  <p>And my service is:</p>
  
  <pre><code>import {Injectable} from '@angular/core';
  import {environment} from '../environments/environment';
  import {Observable} from 'rxjs';
  import {JwtHelperService} from '@auth0/angular-jwt';
  import {HttpClient, HttpHeaders} from '@angular/common/http';
  
  declare let Keycloak: any;
  
  const JWT_TOKEN_NAME: string = 'token';
  
  @Injectable()
  export class KeycloakService {
  
    static auth: any = {};
  
    constructor(private httpClient: HttpClient, private jwtHelperService: JwtHelperService) {}
  
    static init(): Promise&lt;any&gt; {
      const keycloakAuth: any = Keycloak({
        url: environment.KEYCLOAK_URL,
        realm: environment.KEYCLOAK_REALM,
        clientId: environment.KEYCLOAK_CLIENTID,
        'ssl-required': 'external',
        'public-client': true
      });
  
      KeycloakService.auth.loggedIn = false;
  
      return new Promise((resolve, reject) =&gt; {
        keycloakAuth.init({onLoad: 'check-sso'})
          .success(() =&gt; {
            console.log('The keycloak client has been initiated successfully');
            KeycloakService.auth.loggedIn = true;
            KeycloakService.auth.authz = keycloakAuth;
            KeycloakService.auth.logoutUrl = environment.KEYCLOAK_URL
              + '/realms/' + environment.KEYCLOAK_REALM + '/protocol/openid-connect/logout?redirect_uri='
              + document.baseURI;
            resolve();
          })
          .error(() =&gt; {
            reject();
          });
      });
    }
  
    static hasRole(role: string): boolean {
      return KeycloakService.auth.authz.tokenParsed.realm_access.roles.indexOf(role) &gt; -1;
    }
  
    static getUsername(): string {
      return KeycloakService.auth.authz.tokenParsed.preferred_username;
    }
  
    static getFullName(): string {
      return KeycloakService.auth.authz.tokenParsed.name;
    }
  
    public login(ussername: string, password: string): Observable&lt;any&gt; {
      console.log('Sending the login credentials to obtain a token');
      const credentials = {username: ussername, password: password};
      const url: string = environment.KEYCLOAK_URL + '/realms/' + environment.KEYCLOAK_REALM
        + '/protocol/openid-connect/token/generate-token';
      return this.httpClient.post(url, credentials);
    }
  
    public logout(): void {
      KeycloakService.auth.loggedIn = false;
      KeycloakService.auth.authz = null;
      window.location.href = KeycloakService.auth.logoutUrl;
    }
  
    public getToken(): Promise&lt;string&gt; {
      return new Promise&lt;string&gt;((resolve, reject) =&gt; {
        if (KeycloakService.auth.authz &amp;&amp; KeycloakService.auth.authz.token) {
          KeycloakService.auth.authz
            .updateToken(5) // Refresh the token if it will expire in n seconds or less
            .success(() =&gt; {
              resolve(&lt;string&gt;KeycloakService.auth.authz.token);
            })
            .error(() =&gt; {
              reject('Failed to refresh the auth token');
            });
        } else {
          reject('The auth token could not be retrieved because the user was not logged in');
        }
      });
    }
  
    public isAuthenticated(): boolean {
      const token = this.getJwtTokenFromLocalStorage();
      return (token &amp;&amp; !this.jwtHelperService.isTokenExpired(token));
    }
  
    public getTokenExpirationDate() {
      const token = this.getJwtTokenFromLocalStorage();
      return this.jwtHelperService.getTokenExpirationDate(token);
    }
  
    public getDecodedToken() {
      const token = this.getJwtTokenFromLocalStorage();
      return this.jwtHelperService.decodeToken(token);
    }
  
    public getJwtTokenFromLocalStorage(): string {
      return localStorage.getItem(JWT_TOKEN_NAME);
    }
  
    public setJwtTokenToLocalStorage(token: string): void {
      localStorage.setItem(JWT_TOKEN_NAME, token);
    }
  
    public getJwtTokenName(): string {
      return JWT_TOKEN_NAME;
    }
  
  }
  </code></pre>
  
  <p>All my dependencies are:</p>
  
  <pre><code>"@angular/animations": "^5.2.0",
  "@angular/common": "^5.2.0",
  "@angular/compiler": "^5.2.0",
  "@angular/core": "^5.2.0",
  "@angular/forms": "^5.2.0",
  "@angular/http": "^5.2.0",
  "@angular/platform-browser": "^5.2.0",
  "@angular/platform-browser-dynamic": "^5.2.0",
  "@angular/router": "^5.2.0",
  "@auth0/angular-jwt": "^1.0.0",
  "angular-in-memory-web-api": "^0.5.3",
  "core-js": "^2.4.1",
  "jwt-decode": "^2.2.0",
  "keycloak-js": "^3.4.3",
  "npm": "^5.6.0",
  "rxjs": "^5.5.6",
  "zone.js": "^0.8.19"
  </code></pre>
  
  <p>UPDATE: I split the service into two services, one <code>KeycloakService</code> dealing with the <code>Keycloak</code> server and an <code>AuthService</code> sort of encapsulating it, so as to have smaller sized services. The issue remained though, and I had to go for David's solution and the workaround he mentioned. And my new <code>AuthService</code> has the following constructor:</p>
  
  <pre><code>@Injectable()
  export class AuthService {
  
    //  constructor(private jwtHelperService: JwtHelperService) {} TODO
    jwtHelperService: JwtHelperService;
    constructor(private injector: Injector) {
      let jwtHelperService = this.injector.get(JwtHelperService);
    }
  </code></pre>