I have a settings page where users can save some config variables, such as a Username. The user can also change the username on that page. But when I go to another Component (page) and back, the username isn't saved.
I also want to show the username in the other components. How do I do that? With a global variable?
Structure: - App - app.ts (main) - setting.ts - someOtherComponent.ts
What you need is a service to maintain the state of your variables. You would then be able to inject that service into any component to set or get that variable.
Here's an example (/services/my.service.ts):
You would probably want to put that service in the providers array of your app's bootstrap function (which might be in your main app component file, or in a separate file depending on how you like to do things).
In your main app file (/app.ts):
You needn't have COMMON_DIRECTIVES and the other all caps items in the array, but those are commonly included just to make it so that you don't have to configure them in each component you write.
Then you would access the service from within a component like this (/components/some-component.ts):
You might also want to add to the service so that it saved the value to somewhere (semi) permanent so that it could be accessed the next time the user entered the application.
I have the same problem, most of the component needs loggedInUser information. For eg : username, preferred language, preferred timezone of the user etc.
So for this, once user logs in, we can do the following :
If all the information is in JWT Token or /me RESTful Api, then you can decode the token in one of the service.
eg: user.service.ts
which holds three public Behaviour subject, whoever is listening to this variable, will get the value if it is change. Please check the rxjs programming style.
and now wherever this variable are required, just subscribe from that component.
For eg: NavComponent will definitely needs username. hence the code will like this below:
Hence, reactive programming gives better solution to handle the dependency variable.
The above also solves the problem if the page is hard refresh, as I am storing the value in localstorage and fetching it in constructor.
Please note : It is assumed that logged in user data is coming from JWT token, we can also the same service(UserHttpService) if the data is coming from Restful Api. Eg: api/me
This might be an overkill in your current situation, but if you are going to grow your application into a larger one, this might save you a lot of troubles down the line. That said, I believe Angular with Redux-like store is a really powerful combination. My suggestion is to use
ngrx/store
module.Source:
ngrx/store
GitHub repoThe code below should outline all steps you need to follow to integrate the
ngrx/store
into your application. For the sake of brevity, I have omitted any existing code you might have and all imports which you will need to add.Install the Module
Create a Reducer
Import the StoreModule
Create Interface for Settings Reducer
Create a Store Interface
Create Settings Service
Settings Component Controller
Settings Component Template
With the setup outlined above you can then inject the
SettingsService
into any component and display the value in its template.The same way you can also update the value of the
store
from any component by usingthis.settingsService.update({ ... });
and the change will be reflected on all places which are using that value - be it a component via anasync
pipe or another service via.subscribe()
.Vladimir correctly mentioned about
ngrx
.I would use a service with
Subject
/BehaviourSubject
andObservable
toset
andget
the state (values) that I need.We discussed here Communication between multiple components with a service by using Observable and Subject in Angular 2 how you can share values in multiple components that do not have
parent
-child
orchild
-parent
relationship and without importing external library asngrx
store.You would need a service this so you can inject in wherever you need it.:
You could provide this service in all your modules but there is a chance you will get multiple instances. Therefore we will make the service a singleton.
You should call the
forRoot
method only in yourAppModule
: