Save Variable Globally - AngularJs 2 + Typescript

5,709 views
Skip to first unread message

Hiren Modi

unread,
Apr 10, 2016, 8:57:46 PM4/10/16
to AngularJS
Hi Guys,

Please help me to know how to save the Json Variable values globally in the system developed in Angularjs2 + Typescript.

In Angularjs 1, we were using Rootscope to globally declared the values to access. Is there any way to handle this in angularjs2 + Typescript?

It would be good if you can provide the sample example as well.

Thanks,
Hiren

Zlatko Đurić

unread,
Apr 11, 2016, 5:01:58 AM4/11/16
to AngularJS


On Monday, April 11, 2016 at 2:57:46 AM UTC+2, Hiren Modi wrote:
 
Please help me to know how to save the Json Variable values globally in the system developed in Angularjs2 + Typescript.

In Angularjs 1, we were using Rootscope to globally declared the values to access. Is there any way to handle this in angularjs2 + Typescript?

 

You should simply use a service available from the app scope. Here are some examples. Note that I've just dived into Angular2 and I might be providing suboptimal examples, but they work for me.

Basically your main (app) component can look like this:

import { Component } from 'angular2/core';

class GlobalSettings {

  public backendUrl: string = 'https://example.com/api';
  public authToken: string;
  public someOtherGlobalValue: number = 6;
}

@Component({

  selector: 'app',
  providers: [GlobalSettings]
  template: '<div> This is the template placeholder </div>'
})
export class App {

  constructor (private globalSettings: GlobalSettings) {}
}


Now, note the line `providers: [GlobalSettings]` there. When you add a provider like that, then the current component and all of the child components will share the same instance of the global settings. And since this is the main component, global service is shared among all the other components (unless they override it for themselves).

Now, you obviously wanna move the global settings to it's own file, right?

So you have global-settings.ts:

export class GlobalSettings {

  public backendUrl: string = 'https://example.com/api';
}

Then Angular2 will "provide" your App component and it's descendants an instance of the component:

import { Component } from 'angular2/core';

// import the settings
import { GlobalSettings } from './global-settings';
import { SubComponent } from './subcomponent';
@Component({

  selector: 'app',
  providers: [GlobalSettings]
  template: '<subcomponent></subcomponent>',
  directives: [SubComponent]
})
export class App {}

Note how the App doesn't even have to use the settings, just provide it.

Then your subcomponent simply asks for the instance in it's constructor:

import { Component } from 'angular2/core';

// import the settings
import { GlobalSettings } from './global-settings'
@Component({

  selector: 'subcomponent',
  template: '<div>We'll be connecting to {{ backendUrl }}</div>'
})
export class SubComponent {

  public backendUrl: string;
  constructor(private globalSettings: GlobalSettings) {

    this.backendUrl = globalSettings.backendUrl;
  }
}


So far, so good. But what if you want to update those global settings from around the app?

Let's say one component updates a value, another one reacts to them? Use an Observable.

import { Observable } from 'rxjs/Observable';
export class GlobalSettings {
  
  // Our monitored shared global value
  // An Observable object that other components will subscribe to if they want
  // updates
  public globalValue$: Observable<string>;

  // And here we'll shoot updates from.
  private observer: any; // I don't know the proper type for this.

  constructor() {

    this.globalValue$ = new Observable(observer => this.observer = observer);
  }

  // When a component wants to update the value, come in here.
  public updateValue(value) {

    // just retransmit the value. Alternatively you can check if it matches one
    // of desired values, if the caller has the correct authorization or similar.
    // We also need to check if there _is_ an observer. If nobody subscribed to
    // the observable, the observer would not exist and this would error out.
    if (this.observer) {

      this.observer.next(value);
    }
  }
}


Now, the usage is simple:

// the component that wants to listen to changes
class ListeningComponent {
  
  constructor(private globalSettings: GlobalSettings) {

    this.globalSettings.globalValue$.subscribe(newValue => console.log(`New global value: ${newValue}.`));
  }
}

// The component that wants to make updates, even if it's the same one:

  this.globalSettings.updateValue('new value here');


You would also use the similar pattern if you want to asynchronously update the global state (e.g. read initial values from a config.json or remote server) - an observer that emits those values.

Anyway, hope that helps.

than...@siliconprime.com

unread,
Jul 18, 2018, 1:55:01 AM7/18/18
to Angular and AngularJS discussion
It not working when we add this.globalSettings.globalValue$.subscribe(newValue => console.log(`New global value: ${newValue}.`)); to 2 component. it only working in 1 component, another component will not sub.

Zlatko Đurić

unread,
Jul 18, 2018, 2:17:20 AM7/18/18
to Angular and AngularJS discussion
Hi thang,

This thread is two years old, you can find better solutions on angular site now.Take a look at the latest Angular versions and Angular CLI (ng) and look into things like environment setup and dependency injection.

But if you insist on this solution above, and without seeing your code, I'm pretty sure this is because you provide the GlobalSettings into each of the two components - then the instances are not shared. Try providing the service only in app module.

Zlatko

than...@siliconprime.com

unread,
Jul 18, 2018, 3:27:45 AM7/18/18
to Angular and AngularJS discussion
ok Thanks, i got it. i import it in two component
Reply all
Reply to author
Forward
0 new messages