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
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?
Guard your route with a CanActivate class using a Promise which loads the config settings should also work.
Use the appSettings.service with a function just like the one returning a promise
And the CanActivate guard as below:
This will ensure that your settings are available when the corresponding components are constructed. (using the APP_INITIALIZER did not restrict the constructor being called, so I had to use this technic, Also please make sure, you dont export all the components in the exports:[] in the module)
To guard the routes and ensure settings are loaded before the constructors are called, please use the usual canActivate option in the path for the route definition
The initialization of appsettings should happen before the constructor for AbcComponent is called, this is tested and works in Angular 2.0.1
Your
AppConfig
provider in@NgModule()
shadows the provider passed tobootstrapModule()
With How to pass parameters rendered from backend to angular2 bootstrap method you should get what you want.
I ended up adding object to globals.
// ===== File globals.ts
// ===== File app.config.ts
// ===== File index.html or cshtml
// ===== File main.ts
// ===== File app.module.ts
// ===== File intro.component.ts