6

================================================================

EDIT : SOLUTION After upgrading to 2.0 Final - Passing server parameters to ngModule after RC5 upgrade

==================================================================

Any way to have server parameters passed to an Angular 2 application?

i.e. I would like to use the MVC object "HttpContext.User.Identity.Name" and have it injectable anywhere in my angular 2 app.

In angular 1 this was possible using ng ".constant" and serializing .Net objects to JSON in index.cshtml.

Looks like there's a way to pass params but this doesn't work with .Net code. Define global constants in Angular 2

        //HTML - Bootstrapping
        <script>

            System.import('app/main').then(null, console.error.bind(console));
            //I WOULD LIKE TO PASS SOME PARAMS TO APP/MAIN HERE
        </script>

FINAL SOLUTION: (big thanks to Thierry)

index.cshtml:

<script>
    System.import('app/main').then(
        module => 
            module.main(
                {
                    name: '@User.Identity.Name',
                    isAuthenticated: User.Identity.IsAuthenticated.ToString().ToLowerInvariant(),
                }
            ),
        console.error.bind(console)
    );
</script>

main.ts:

...
    import {provide} from '@angular/core';
...

    export function main(params) {
        bootstrap(AppComponent,
            [
                provide('Name', { useValue: params.name }),
                provide('IsAuthenticated', { useValue: params.isAuthenticated }),
                ROUTER_PROVIDERS,
                HTTP_PROVIDERS,
                LoggerService,
                AuthenticationService
            ]);
    }

Usage:

import {Component, Injectable, Inject} from '@angular/core';
import {ROUTER_DIRECTIVES} from '@angular/router';

@Component({
    selector: 'navbar',
    templateUrl: 'app/components/header/navbar.html',
    directives: [ROUTER_DIRECTIVES]
})
export class SomeComponent {

    constructor(@Inject('Name') public username: string) {

    }

}

0

3 Answers 3

9
+50

An option would be to add a method in the module you import. So you can then call it to provide the object you want.

Here is a sample of the app/main module:

import {bootstrap} from '...';
import {provide} from '...';
import {AppComponent} from '...';

export function main(params) {
  let userIdentityName = params.name; // for example
  bootstrap(AppComponent, [
    provide('userIdentityName', { useValue: userIdentityName })
  ]);
}

Then you can import it from your HTML main page like this:

<script>
  System.import('app/main').then((module) => {
    module.main({
      userIdentityName: 'something from asp.net'
    });
  });
</script>

Update

With latest versions of Angular, you need to leverage modules this way:

export const USER_IDENTITY_NAME_TOKEN =
  new  InjectionToken('userIdentityName');

@NgModule({
  (...)
  providers: [
    {
      provide: USER_IDENTITY_NAME_TOKEN,
      useValue: userIdentityName
    }
  ]
})
export class MainModule() { }
Sign up to request clarification or add additional context in comments.

5 Comments

any idea how this could be done after RC5? ngModule is giving me a lot of problems with my params.
This doesn't work in @Angular RC6. "provide" is no longer supported in @angular/core. Any workaround please
Thank for the tips but where I can find "bootstrap" and "provide" please ?
@amorel I updated my answer for latest versions of Angular... hope it'll help you ;-)
Is there any way to achieve this without using systemjs ?
4

thanks for info, for those using platformBrowserDynamic to boot:

main.ts:

//platformBrowserDynamic().bootstrapModule(asstModule);

export function main(appSettings: any) {   
    platformBrowserDynamic([{ provide: 'AppSettings', useValue: appSettings }]).bootstrapModule(asstModule);
}

Comments

0

With a .NET Core server, I recommend to use a the IOptions<> and a ViewComponent

Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    // ...

    services.AddOptions();
    services.Configure<Models.EnvironmentSettings>(Configuration.GetSection("client"));
    services.Configure<Models.EnvironmentSettings>(options =>
    {
        options.OtherSetting = "Other";
    });

    services.AddMvc();
}

Models/EnvironmentSettings.cs

public class EnvironmentSettings
{
    public string OtherSetting { get; set; }
    public string LoginUrl { get; set; }
}

appsettings.json

{
    "client": {
        "LoginUrl": "http://localhost:45290/Token"
    }
}

Controllers/Components/BootstrapViewComponent.cs

public class BootstrapViewComponent : ViewComponent
{
    private IOptions<EnvironmentSettings> environmentSettings;

    public BootstrapViewComponent(
        IOptions<EnvironmentSettings> environmentSettings
    )
    {
        this.environmentSettings = environmentSettings;
    }

    public async Task<IViewComponentResult> InvokeAsync()
    {
        return View(environmentSettings.Value);
    }
}

Views/Shared/Components/Bootstrap/Default.cshtml

@model YourApp.Models.EnvironmentSettings
<script>
    System.import('app')
        .then(function (module) {
            module.main({
                other: "@Model.OtherSetting",
                loginUrl: "@Model.LoginUrl"
            })
        })
        .catch(function (err) {
            console.error(err);
        });
</script>

Views/Shared/_Layout.cshtml

<head>
...
@await Component.InvokeAsync("Bootstrap")
</head>

main.ts

export function main(settings: any) {
    platformBrowserDynamic([{ provide: 'EnvironmentSettings', useValue: settings }]).bootstrapModule(AppModule);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.