Search code examples
angulartypescriptangular2-servicesangular2-di

Angular2: inject server side config into service


I'm using Angular 2.0.0 with TypeScript in ASP.NET Core. My goal is to create AppConfig service in my app, based on server-side variables. With a help from few other answers, I was able to create following code:

Index.cshtml

<app>
    <i class="fa fa-spin fa-5x fa-spinner"></i>
</app>

<script>
    System.import('/app/main').then((m) => {
        var config = {
            apiUrl: @options.ApiServerUrl
        };

        m.RunApplication(config);
    }, console.error.bind(console));
</script>

app.config.ts

import { Injectable } from "@angular/core";

@Injectable()
export class AppConfig {
    apiUrl: string;
}

main.ts

import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";

import { AppModule } from "./app.module";
import { AppConfig } from "./app.config";

export function RunApplication(config: Object) {

    var appConfig = new AppConfig();
    appConfig.apiUrl = config["apiUrl"];

    console.log('Created config: ', appConfig);

    platformBrowserDynamic()
        .bootstrapModule(AppModule, [{ providers: [{ provide: AppConfig, useValue: appConfig }] }])
        .catch(err => console.error(err));
}

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { HttpModule } from "@angular/http";
import { AppRouting, AppRoutingProviders } from "./app.routes";
import { AppConfig } from "./app.config";
import { AppComponent } from "./app.component";
import { DashboardComponent } from "./dashboard/dashboard.component";
import { DashboardService } from "./dashboard/dashboard.service";

@NgModule({
    declarations: [
        AppComponent,
        DashboardComponent
    ],
    imports: [
        BrowserModule,
        HttpModule,
        AppRouting
    ],
    providers: [
        AppRoutingProviders,
        AppConfig,
        DashboardService
    ],
    bootstrap: [AppComponent],
})
export class AppModule { }

dashboard.service.ts

import { Http } from "@angular/http";
import { Injectable } from "@angular/core";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/map";
import { AppConfig } from "../app.config";

@Injectable()
export class DashboardService {

    constructor(private appConfig: AppConfig, private http: Http) {
        console.log('Injected config: ', appConfig);
        console.log('Injected apiUrl: ', appConfig.apiUrl);
    }
}

Outpup from Chrome console

Outpup from Chrome console

As you can see for some reason created and injected AppConfig are not the same, and apiUrl value does not appear in DashboardService. I suspect that error is somewhere in here:

bootstrapModule(AppModule, [{ providers: [{ provide: AppConfig, useValue: appConfig }] }])

but I'm quite new to Angular2 and don't know how to fix it. Can you point me where the problem is?


Solution

  • Your AppConfig provider in @NgModule() shadows the provider passed to bootstrapModule()

    With How to pass parameters rendered from backend to angular2 bootstrap method you should get what you want.