19

Angular 2 question only:

Whats the best way to store global variables like authentication token or base url (environment settings) so that all classes can have access to them without loosing them on refresh?

So when I login I will give the user a auth token and normally store it in the $rootscope for angular 1.x.

Sangwin Gawande
  • 6,028
  • 8
  • 40
  • 58
AngularM
  • 13,932
  • 27
  • 78
  • 151
  • Configure the injector. This way you can request to get the values injected wherever you need access to them. I don't know the actual syntax therefore only as comment. See for example http://blog.thoughtram.io/angular/2015/05/18/dependency-injection-in-angular-2.html – Günter Zöchbauer Nov 08 '15 at 20:38

4 Answers4

15

Well to create really global scope data you should register your class\object\value during the app bootstrapping as dependency parameter to the bootstrap function

bootstrap(MyApp,[MyGlobalService]);

This will register your service MyGlobalService (infact it can be a object or factory function or your own provider) at the root level. This dependency now can be injected into any component.

Unlike Angular1 there are multiple Injectors available for an Angular2 app, with one-to-one mapping between components and injectors. Each component has its own injector.

The Angular developer guide has some good example of such registrations. See the guide on Dependency Injection.

The other option has already been highlighted by @Yaniv.

Chandermani
  • 42,177
  • 11
  • 82
  • 86
5

In my opinion storing a parameter like this on global variable like $rootScope is considered a bad practice. On Angular 1.x you should use a service (singelton) in order to fetch this data from everywhere. This way your data will be available from everywhere - you can inject your service and get the value. You could also mock/spy this service when unit testing.

Angular 2 applications should be built as a component tree. I guess that the best solution for your scenario will be to save it using a service under the root component and pass it to child components as an input.

This way your data will be controlled from your main component. It will be immutable (child components cannot change it) and your components will not have external references (it is an important step towards a good component architecture).

If you still want to do it the "Angular 1.x way", I guess that you could inject this service everywhere and use its values. It is less preferred options but it is better than global variables!

Hope that was helpful.

Yaniv Efraim
  • 6,200
  • 6
  • 48
  • 92
  • 2
    According to you i have to make class/service then declare global variable here that i want to use and then after i have to import this service in all child components ? by using this if i have 50+ classes/component then i have to import this service 50+times not its too long process ? – Pardeep Jain Dec 14 '15 at 11:30
  • A class dependent on 50+ classes is most probably a bad design. Even if there are n number of services, they can be grouped into umbrella services for services that are mostly used together. Still it's better to have smaller components with less number of dependencies. Such components can be combined together to achieve the desired functional behavior – Chandermani Dec 15 '15 at 03:32
  • Unfortunately this is needed when it comes to doing something like rendering SVGs. Each SVG needs a separate template and so had to become a component. Of course we have dozens of them, and it would make a huge code mess if we had to register them with every view component. In theory not allowing for global scope is a good thing, but it isn't practical for many real applications. – Project707 Feb 24 '16 at 18:10
  • 3
    @PardeepJain that's the Angular 2 way, a lot of repeated things – sites Jan 17 '17 at 21:22
  • *"save it using a service under the root component and pass it to child components as an input."* That's a good idea. Using DI is such a slippery slope, getting every [ friggin ] module to Fan-Out to every other [ friggin ] module. **That's why in Angular 1.x I used to flatten out all my cardinal data (eager-loaded data, US-State-Codes, etc) onto `$rootScope` and reference it as `$root`**. That was my *only* global to my views, as each controller/directive used `controllerAs: 'thus'` so I wouldn't have access to *any* other scope. NG2 takes care of all that now but I still wish we had `$root`. – Cody Jan 25 '17 at 00:46
2

In your specific scenario you would actually want to store token in localstorage since a page refresh will cause you to loose token value stored in memory.

Prabhat
  • 3,111
  • 3
  • 26
  • 35
0

you can also use ngrx/store, for global data(except jwt token) and pass it to 'connected' components in redux way