23

I have a global js variable defined below (@Url is an ASP.Net MVC html helper it will get converted to a string value):

<script>
  var rootVar = '@Url.Action("Index","Home",new { Area = ""}, null)';
  System.import('app').catch(function(err){ console.error(err); });
</script>

How do I access rootVar in an angular2 component? I used to use the window service in angular 1.5, is there an analogous way of doing that in angular2?

Specifically, I want to use that rootVar variable to help generate the templateUrl in this component:

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

@Component({
    selector: 'home-comp',
    templateUrl: '../Home/Root'
})

export class HomeComponent {   
    constructor( ) {  }
}
2
  • 1
    If it's global, it's global. That means that any piece of JS code can access the variable. Commented Jun 6, 2016 at 16:50
  • 1
    You can look at this Thierry`s answer stackoverflow.com/questions/37337185/… Commented Jun 6, 2016 at 16:50

6 Answers 6

38

Within your component you could reference window to access the global variables like so:

rootVar = window["rootVar"];

or

let rootVar = window["rootVar"];
Sign up to request clarification or add additional context in comments.

Comments

13

You need to update the file that bootstraps your application to export a function:

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

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

Now you can provide the variable from the index.html file this way:

<script>
  var rootVar = '@Url.Action("Index","Home",new { Area = ""}, null)';
  System.import('app/main').then((module) => {
    module.main(rootVar);
  });
</script>

Then you can inject the rootVar into components and services this way:

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

@Component({
  selector: 'home-comp',
  templateUrl: '../Home/Root'
})
export class HomeComponent {   
  constructor(@Inject('rootVar') rootVar:string ) {  }
}

2 Comments

Thanks, I was able to access the variable in my component following your example, but I'm running into a new problem. Now that i have the rootVar being injected into the constructor I can't seem to use it to modify the component templateUrl. @Component({ selector: 'home-comp', templateUrl: '..{{baseUrl}}Home/Root' }) export class HomeComponent { baseUrl: string; constructor( @Inject('rootVar') rootVar: string) { this.baseUrl = rootVar; } }
You're welcome! In fact, you can't use the variable this way to build the tempalteUrl path. One is at the level of the class and other of the instance... In your case, I would try to extend the UrlResolver class and inject your variable in it. See this link: angular.io/docs/ts/latest/api/compiler/UrlResolver-class.html.
11

In the component file, outside component class definition, declare rootVar, and it will become available in the component constructor:

declare var rootVar: any;

then

@Component(...)
export class MyComponent {
  private a: any;

  constructor() {
    this.a = rootVar;
  }
}

1 Comment

Important to note. I could not get the declare outside of the component class to be visible to any methods in the component class. You need to set an instance variable in constructor to reference the global variable and then reference that variable in your methods
7

Here don't forget to wash your hands... Angular is just javascript

//Get something from global
let someStuffFromWindow= (<any>window).somethingOnWindow;

//Set something
(<any>window).somethingOnWindow="Stuff From Angular";

This is bad for some reason.. you should feel bad!

Go ahead and use that find and replace fuction for window. with (<any>window).

6 Comments

window['somethingOnWindow'] looks cleaner. Don't ask me why
why? @redent84 (sorry couldn't help it)
I think in general [] is used for dynamic fields. Using property.value is used for none dynamic fields (see airbnb styleguide).
Thanks. Had to search for a long time to find a solution without 5 files and 40 lines of code.
I prefer with the type casting, so it looks a bit complicated to fit with the rest of the code, and I can pretend I do smart Typescript
|
3

A different approach would be to export your var, for ex:

  export var API_ENDPOINT = '@Url.Action("Index","Home",new { Area = ""}, null)';

and then import that in your component

import {API_ENDPOINT }

Comments

0

In HTML template you can use method get

<span>{{getGlobalData('rootVar')}}</span>

And create method in component like:

get getGlobalData() {
    // Closure workaround
    return function(rootVarName) {
        return window[rootVarName];
    }
}

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.