title: Angularjs2 - preload server configuration before the application starts
body: <p>I am working with Angular2 RC5. I would like to be able to load my server IP address and some other configuration parameters before my app boots up. How can I do this in the latest RC5?</p>
  
  <p>I have seen other articles, but they are not helpful:</p>
  
  <ol>
  <li><a href="https://stackoverflow.com/questions/37992671/how-to-preload-a-config-file-in-angular2">How to preload a config file in angular2</a>: The answer provided here is specific to webpack. I am using systemjs.</li>
  <li><a href="https://medium.com/@hasan.hameed/reading-configuration-files-in-angular-2-9d18b7a6aa4#.m8lontnas" rel="noreferrer">https://medium.com/@hasan.hameed/reading-configuration-files-in-angular-2-9d18b7a6aa4#.m8lontnas</a>: This is for the older version of Angular2. Some of the classes used are deprecated.</li>
  </ol>
  
  <p>Any help would be greatly appreciated.</p>
  
  <p><strong>Edit</strong></p>
  
  <p>I tried to use the APP_INITIALIZER as follows in my app.module.ts:</p>
  
  <pre class="lang-ts prettyprint-override"><code>    import { NgModule, provide, APP_INITIALIZER }       from "@angular/core";
      import { ConfigService } from "./shared/services/config.service";
      @NgModule({
          declarations: [AppComponent],
          imports: [BrowserModule,
              routes,
              FormsModule,
              HttpModule],
          providers: [AuthService,
              Title,
              appRoutingProviders,
              ConfigService],
          bootstrap: [AppComponent
              , provide(APP_INITIALIZER,
                  {
                      useFactory: (config: ConfigService) =&gt; () =&gt; config.load(),
                      deps: [ConfigService], multi: true
                  })]
      })
      export class AppModule { }
  </code></pre>
  
  <p>This is my config.service.ts file:</p>
  
  <pre class="lang-ts prettyprint-override"><code>    import { Config } from "../model/config";
  
      export class ConfigService {
          constructor() {
          }
  
          load(): Promise&lt;Config&gt; {
              let config: Config = new Config("localhost", "5050");
              return Promise.resolve(config);
          }
      }
  </code></pre>
  
  <p>Note that I will eventually re-write load to actually read a property or some such file to load configuration.</p>
  
  <p>This is what config.ts looks like:</p>
  
  <pre class="lang-ts prettyprint-override"><code>export class Config {
  
      constructor(
          private machine: string,
          private port: string
      ) {
      }
  
      private base_url: string = "http://" + this.machine +
      this.port + "/";
  
      public loginURL: string = this.base_url + "login";
  }
  </code></pre>
  
  <p>I am getting a compile error</p>
  
  <pre class="lang-ts prettyprint-override"><code>public/app/app.module.ts(27,11): error TS2345: Argument of type '{ declarations: (typeof AppComponent ...' is not assignable to parameter of type 'NgModuleMetadataType'.
    Types of property 'bootstrap' are incompatible.
      Type '(typeof AppComponent | Provider)[]' is not assignable to type '(Type | any[])[]'.
        Type 'typeof AppComponent | Provider' is not assignable to type 'Type | any[]'.
          Type 'Provider' is not assignable to type 'Type | any[]'.
            Type 'Provider' is not assignable to type 'any[]'.
              Property '[Symbol.iterator]' is missing in type 'Provider'.
  </code></pre>
  
  <p><strong>Edit 2</strong></p>
  
  <p>I move on to the next step. Update ConfigService to read a json file using http.get. Now I get an error. Here are the updated files:</p>
  
  <pre class="lang-ts prettyprint-override"><code>export class ConfigService {
      private config: Config;
          constructor(private http: Http) {
      }
  
      load(): Promise&lt;Config&gt; {
              this.http.get("/blah/config.json")
                   .map(res =&gt; res.json())
                   .subscribe((env_data) =&gt; {
                       console.log(env_data);
                    });
          this.config = new Config("localhost", "5050");
          return Promise.resolve(this.config);
      }
  
      getConfig(): Config {
          return this.config;
      }
  }
  </code></pre>
  
  <p>Here is the providers section in NgModule class</p>
  
  <pre class="lang-ts prettyprint-override"><code>    providers: [AuthService,
      Title,
      appRoutingProviders,
      ConfigService,
      {
          provide: APP_INITIALIZER,
          useFactory: (config: ConfigService) =&gt; () =&gt; config.load(),
          deps: [ConfigService, Http],
          multi: true
      }],
  </code></pre>
  
  <p>Note that in RC6 I am not able to import HTTP_PROVIDERS since I get the error that these are not defined in the http module anymore. This is why I tried Http.</p>
  
  <p>On runtime, I get following error</p>
  
  <pre class="lang-ts prettyprint-override"><code>(index):27 Error: Error: Can't resolve all parameters for ConfigService: (?).(…)(anonymous function) @ (index):27
  ZoneDelegate.invoke @ zone.js:332
  Zone.run @ zone.js:225(anonymous function) @ zone.js:591
  ZoneDelegate.invokeTask @ zone.js:365
  Zone.runTask @ zone.js:265
  drainMicroTaskQueue @ zone.js:497
  ZoneTask.invoke @ zone.js:437
  </code></pre>