Advertisement
Advertisement


How can I declare a global variable in Angular 2 / Typescript?


Question

I would like some variables to be accessible everywhere in an Angular 2 in the Typescript language. How should I go about accomplishing this?

2019/05/12
1
166
5/12/2019 1:01:08 AM

Accepted Answer

Here is the simplest solution w/o Service nor Observer:

Put the global variables in a file an export them.

//
// ===== File globals.ts    
//
'use strict';

export const sep='/';
export const version: string="22.2.2";    

To use globals in another file use an import statement: import * as myGlobals from 'globals';

Example:

// 
// ===== File heroes.component.ts    
//
import {Component, OnInit} from 'angular2/core';
import {Router} from 'angular2/router';
import {HeroService} from './hero.service';
import {HeroDetailComponent} from './hero-detail.component';
import {Hero} from './hero';
import * as myGlobals from 'globals'; //<==== this one (**Updated**)

export class HeroesComponent implements OnInit {
    public heroes: Hero[];
    public selectedHero: Hero;
    // 
    //
    // Here we access the global var reference.
    //  
    public helloString: string="hello " + myGlobals.sep + " there";

         ...

        }
    }

Thanks @eric-martinez

2020/03/02
199
3/2/2020 8:55:02 AM


A shared service is the best approach

export class SharedService {
  globalVar:string;
}

But you need to be very careful when registering it to be able to share a single instance for your whole application. You need to define it when registering your application:

bootstrap(AppComponent, [SharedService]);

but not to define it again within the providers attributes of your components:

@Component({
  (...)
  providers: [ SharedService ], // No
  (...)
})

Otherwise a new instance of your service will be created for the component and its sub components.

You can have a look at this question regarding how dependency injection and hierarchical injectors work in Angular2:

You can notice that you can also define Observable properties in the service to notify parts of your application when your global properties change:

export class SharedService {
  globalVar:string;
  globalVarUpdate:Observable<string>;
  globalVarObserver:Observer;

  constructor() {
    this.globalVarUpdate = Observable.create((observer:Observer) => {
      this.globalVarObserver = observer;
    });
  }

  updateGlobalVar(newValue:string) {
    this.globalVar = newValue;
    this.globalVarObserver.next(this.globalVar);
  }
}

See this question for more details:

2017/05/23

See for example Angular 2 - Implementation of shared services

@Injectable() 
export class MyGlobals {
  readonly myConfigValue:string = 'abc';
}

@NgModule({
  providers: [MyGlobals],
  ...
})

class MyComponent {
  constructor(private myGlobals:MyGlobals) {
    console.log(myGlobals.myConfigValue);
  }
}

or provide individual values

@NgModule({
  providers: [{provide: 'myConfigValue', useValue: 'abc'}],
  ...
})

class MyComponent {
  constructor(@Inject('myConfigValue') private myConfigValue:string) {
    console.log(myConfigValue);
  }
}
2018/02/15

Create Globals class in app/globals.ts:

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

Injectable()
export class Globals{
    VAR1 = 'value1';
    VAR2 = 'value2';
}

In your component:

import { Globals } from './globals';

@Component({
    selector: 'my-app',
    providers: [ Globals ],
    template: `<h1>My Component {{globals.VAR1}}<h1/>`
})
export class AppComponent {
    constructor(private globals: Globals){
    }
}

Note: You can add Globals service provider directly to the module instead of the component, and you will not need to add as a provider to every component in that module.

@NgModule({
    imports: [...],
    declarations: [...],
    providers: [ Globals ],
    bootstrap: [ AppComponent ]
})
export class AppModule {
}
2016/10/09

IMHO for Angular2 (v2.2.3) the best way is to add services that contain the global variable and inject them into components without the providers tag inside the @Component annotation. By this way you are able to share information between components.

A sample service that owns a global variable:

import { Injectable } from '@angular/core'

@Injectable()
export class SomeSharedService {
  public globalVar = '';
}

A sample component that updates the value of your global variable:

import { SomeSharedService } from '../services/index';

@Component({
  templateUrl: '...'
})
export class UpdatingComponent {

  constructor(private someSharedService: SomeSharedService) { }

  updateValue() {
    this.someSharedService.globalVar = 'updated value';
  }
}

A sample component that reads the value of your global variable:

import { SomeSharedService } from '../services/index';

@Component({
  templateUrl: '...'
})
export class ReadingComponent {

  constructor(private someSharedService: SomeSharedService) { }

  readValue() {
    let valueReadOut = this.someSharedService.globalVar;
    // do something with the value read out
  }
}

Note that providers: [ SomeSharedService ] should not be added to your @Component annotation. By not adding this line injection will always give you the same instance of SomeSharedService. If you add the line a freshly created instance is injected.

2017/01/23

I don't know the best way, but the easiest way if you want to define a global variable inside of a component is to use window variable to write like this:

window.GlobalVariable = "what ever!"

you don't need to pass it to bootstrap or import it other places, and it is globally accessibly to all JS (not only angular 2 components).

2016/06/30