To declare a global variable in TypeScript, create a . d. ts file and use declare global{} to extend the global object with typings for the necessary properties or methods.
We always need to declare global variable file for our angular 8 application because we can set some global variable there like site title, api url etc so you can easily access any where in our application easily. So, in this example, we will create GlobalConstants file for adding global variables in our application.
Declaring a global variable in Angular is easy. You can simply declare at the top of the component (I mean to say a class). If you want to share the variable across the app then you can create a service and use that service everywhere you need the value of the variable.
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
I like the solution from @supercobra too. I just would like to improve it slightly. If you export an object which contains all the constants, you could simply use es6 import the module without using require.
I also used Object.freeze to make the properties become true constants. If you are interested in the topic, you could read this post.
// global.ts
export const GlobalVariable = Object.freeze({
BASE_API_URL: 'http://example.com/',
//... more of your variables
});
Refer the module using import.
//anotherfile.ts that refers to global constants
import { GlobalVariable } from './path/global';
export class HeroService {
private baseApiUrl = GlobalVariable.BASE_API_URL;
//... more code
}
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 whole your 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 Angular 2:
You should 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:
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);
}
}
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 {
}
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 ofSomeSharedService
. If you add the line a freshly created instance is injected.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With