title: APP_INITIALIZER raises "Cannot instantiate cyclic dependency! ApplicationRef_" when used with a custom Http provider that is redirecting
body: <p>I am using a custom Http provider to handle API authentication error. In my CustomHttp, I need to redirect the user to the login page when a 401 status error is emitted by the API. That works fine!</p>
  
  <p>app.module.ts</p>
  
  <pre><code>export function loadCustomHttp(backend: XHRBackend, defaultOptions: AppRequestOptions,
    router: Router, dataHelper: DataHelperService) {
    return new CustomHttp(backend, defaultOptions, router, dataHelper);
  }
  
  @NgModule({
  // some declarations, imports, ...
  providers: [
  // some services ...
   {
        provide: Http,
        useFactory: loadCustomHttp,
        deps: [XHRBackend, RequestOptions, Router, DataHelperService] 
      }
  });
  </code></pre>
  
  <p>custom-http.ts</p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { Http, RequestOptions, RequestOptionsArgs, ConnectionBackend, Request, Response } from '@angular/http';
  import { Router } from '@angular/router';
  import { Observable } from 'rxjs/Observable';
  
  import { DataHelperService } from '../helpers/data-helper.service';
  import { AuthStorage } from '../services/auth/auth-storage';
  
  import 'rxjs/add/observable/throw';
  import 'rxjs/add/observable/empty';
  
  @Injectable()
  export class CustomHttp extends Http {
    constructor(backend: ConnectionBackend, defaultOptions: RequestOptions,
      private router: Router, private dataHelper: DataHelperService) {
      super(backend, defaultOptions);
    }
  
  
    request(url: string | Request, options?: RequestOptionsArgs): Observable&lt;Response&gt; {
      return this.intercept(super.request(url, options));
    }
  
    get(url: string, options?: RequestOptionsArgs): Observable&lt;Response&gt; {
      return this.intercept(super.get(url, options));
    }
  
    post(url: string, body: string, options?: RequestOptionsArgs): Observable&lt;Response&gt; {
      return this.intercept(super.post(url, body, options));
    }
  
    put(url: string, body: string, options?: RequestOptionsArgs): Observable&lt;Response&gt; {
      return this.intercept(super.put(url, body, options));
    }
  
    delete(url: string, options?: RequestOptionsArgs): Observable&lt;Response&gt; {
      return this.intercept(super.delete(url, options));
    }
  
  
  
    intercept(observable: Observable&lt;Response&gt;): Observable&lt;Response&gt; {
      return observable.catch((err, source) =&gt; {
        let token = AuthStorage.getToken();
  
        if (err.status === 401 &amp;&amp; token &amp;&amp; AuthStorage.isTokenExpired())    { 
          // token has expired -&gt; redirecting user to login
          AuthStorage.clearAll();
          this.router.navigate(['auth/login']);
        }
        return Observable.throw(err);
      });
    }
  }
  </code></pre>
  
  <p>Then, I tried to use the <code>APP_INITIALIZER</code> opaque token to get the required settings to initialize my app.</p>
  
  <p>app.module.ts</p>
  
  <pre><code>@NgModule({
  // some declarations, imports, ...
  providers: [
  // some services ...
      ConfigService,
      { 
        provide: APP_INITIALIZER, 
        useFactory: (config: ConfigService) =&gt; () =&gt; config.load(), 
        deps:[ConfigService, Http],
        multi: true
      }
  });
  </code></pre>
  
  <p>config.service.ts</p>
  
  <pre><code>import { Injectable } from '@angular/core';
  import { Http, Response } from '@angular/http';
  import { AppSettings } from '../../environments/app-settings';
  import { Observable } from 'rxjs/Observable';
  
  import 'rxjs/add/operator/toPromise';
  
  @Injectable()
  export class ConfigService {
  
    public settings:AppSettings;
  
    constructor(private http:Http) { }
  
    load() : Promise&lt;AppSettings&gt; {
      let url = '/settings/';
  
      var observable= this.http.get(url)
              .map(res =&gt; res.json());
  
      observable.subscribe(config =&gt; this.settings = config);
      return observable.toPromise();
    }
  
  }
  </code></pre>
  
  <p>This creates an error :</p>
  
  <pre><code>Uncaught Error: Provider parse errors:
  Cannot instantiate cyclic dependency! ApplicationRef_: in NgModule AppModuleNgModuleProviderAnalyzer.parse @ provider_analyzer.js:291NgModuleCompiler.compile @ ng_module_compiler.js:54RuntimeCompiler._compileModule @ runtime_compiler.js:102RuntimeCompiler._compileModuleAndComponents @ runtime_compiler.js:65RuntimeCompiler.compileModuleAsync @ runtime_compiler.js:55PlatformRef_._bootstrapModuleWithZone @ application_ref.js:303PlatformRef_.bootstrapModule @ application_ref.js:285(anonymous function) @ main.ts:18__webpack_require__ @ bootstrap 0e2b412…:52(anonymous function) @ main.bundle.js:86665__webpack_require__ @ bootstrap 0e2b412…:52webpackJsonpCallback @ bootstrap 0e2b412…:23(anonymous function) @ main.bundle.js:1
  </code></pre>
  
  <p>If I comment out the custom Http provider, the error is not shown and the <code>APP_INITIALIZER</code> works as expected.
  If I remove the <code>Router</code> from the Http provider deps declaration, I don't have the error anymore but the my <code>ConfigService.load()</code> function is called twice.</p>
  
  <p>Does anyone knows why this router dependency is causing this cyclic dependency error ?
  How can I prevent my <code>ConfigService.load()</code> function to be called twice ?</p>
  
  <p>If needed, I have created a public repository reproducing the error : <a href="https://github.com/haia212/AngularErrorTestProject" rel="noreferrer">https://github.com/haia212/AngularErrorTestProject</a></p>