6

Okay, so I have a constant variables in the _Layout.cshtml of ASP.Net SPA project and I would to pass them so that Angular will have access to those.

How can I do that?

For example, here is one value I am trying to transfer.

var lenderValues = @Html.Action("GetLenderDropdownValues", "Dropdown");

and here is how my first app.component boots up.

<my-rite-ui>Loading...</my-rite-ui>

I know how to do it in AngularJS 1.x with just constant and injecting that constant whereever is needed, but couldn't figure it out in Angular.

Any help will be highly appreciated.

shammelburg
  • 6,974
  • 7
  • 26
  • 34
premsh
  • 213
  • 3
  • 6
  • 16

3 Answers3

8

It depends on what you want exactly to do but I see two possibilities:

  • Define a constant

This constant needs to be passed when importing your main module. Whereas it's not possible to do this on the import itself. You can import a function and call it with parameters.

Here is a sample of the main module that bootstraps your application:

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

export function main(lenderValues) {
  bootstrap(AppComponent, [
    provide('lenderValues', { useValue: lenderValues })
  ]);
}

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

<script>
  var lenderValues = @Html.Action("GetLenderDropdownValues", "Dropdown");
  System.import('app/main').then((module) => {
    module.main(lenderValues);
  });
</script>

Your lenderValues can be then injected in all elements like a component:

@Component({
  (...)
})
export class SomeComponent {
  constructor(@Inject('lenderValues') lenderValues) {
  }
}
  • Define a parameter on my-rite-ui element

You can specify a parameter at this level but it can't be evaluated. So it's a bit more tedious since you need to serialize it as string with JSON.stringify, gets the element in your component from its corresponding ElementRef and deserialize it using JSON.parse.

Then you can add the data as a provider.

Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
4

The first answer above was my favorite if you are using JIT compilation. We are using JIT for development and AOT for deployment. I couldn't find a good way to make the first answer work with AOT. For reference I followed the AOT cookbook here... Angular AOT cookbook.

The approach below will not work for server side rendering but should suffice for both JIT and AOT client side rendering.

1) In the razor view, _layout.cshtml for example, just put a script block and set a JSON object on the window interface. I placed this block within the "head" tag but doesn't really matter. The values for the JSON keys can be determined by any razor syntax.

<script type="text/javascript">
    window.appContext = {
        userName: '@("test".ToUpper())',
        isAdmin: @(1 == 1 ? "true" : "false")
    };
</script>

2) Create an app context service and wire up in appropriate module and inject into components for usage, if you need help with this just comment and I'll supply more info.

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

/*
    must match definition in SCRIPT tag that is seeded from razor
*/
interface IAppContext {
    userName: string;

    isAdmin: boolean;
}

/*
    
*/
@Injectable()
export class AppContextService implements IAppContext {

    userName: string;

    isAdmin: boolean;

    constructor() {
        var appContextBootstrap: IAppContext = (<IAppContext>(<any>window).appContext);

        this.userName = appContextBootstrap.userName;
        this.isAdmin = appContextBootstrap.isAdmin;
    }

}

3) reference and use the app context service throughout the application.

import { Component } from '@angular/core';

import { AppContextService } from './appContext.service'

@Component({
    moduleId: module.id,
    selector: 'story-app',
    templateUrl: 'app.component.html'
})
export class AppComponent {
    AppConfig: any;
    constructor(private appContext: AppContextService) { }

    ngOnInit() {

        alert('hi - ' + this.appContext.userName);
    }
}
Jeff Marino
  • 1,156
  • 1
  • 7
  • 7
0

What is the problem? I have easily get value from an HTML page like this.

HTML

<script type="text/javascript"> var getThisValue='I want this string in component'; </script>

<html>
  <head>
    <base href="/">
    <title>Angular 2 - Tour of Heroes</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="styles.css">

    <!-- 1. Load libraries -->
     <!-- Polyfill(s) for older browsers -->
    <script src="node_modules/es6-shim/es6-shim.min.js"></script>

    <script src="node_modules/zone.js/dist/zone.js"></script>
    <script src="node_modules/reflect-metadata/Reflect.js"></script>
    <script src="node_modules/systemjs/dist/system.src.js"></script>

    <!-- 2. Configure SystemJS -->
    <script src="systemjs.config.js"></script>
    <script>
      System.import('app').catch(function(err){ console.error(err);  });
    </script>    

    <script type="text/javascript">
      var getThisValue='I want this string in component';
    </script>
  </head>
  <!-- 3. Display the application -->
  <body>
    <my-app>Loading...</my-app>
  </body>
</html>

Call Main Component file

alert(getThisValue);

    import { bootstrap } from '@angular/platform-browser-dynamic';
    import { HTTP_PROVIDERS } from '@angular/http';
    import { AppComponent } from './app.component';
    //import { enableProdMode } from '@angular/core';

    //enableProdMode();

    bootstrap(AppComponent, [HTTP_PROVIDERS]);

    alert(getThisValue);

It's work for me

On thing I have notice in your code is you should use '' mark to access url.

Replace this

var lenderValues = @Html.Action("GetLenderDropdownValues", "Dropdown");

with this

var lenderValues = '@Html.Action("GetLenderDropdownValues", "Dropdown")';

This is the simplest option to access value from HTML of course not a proper way. To access this value you need to define a constant as defined in Thierry Templier answer above.

Jitendra Tiwari
  • 1,651
  • 3
  • 14
  • 28