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.
RxJS powered state management for Angular applications, inspired by Redux
Source: ngrx/store
GitHub repo
The 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
npm install --save ngrx/core ngrx/store
Create a Reducer
export const SETTINGS_UPDATE = 'SETTINGS_UPDATE';
const initialState = {
username: ''
};
export function settingsReducer(state: Object = initialState, action: Action) {
switch (action.type) {
case SETTINGS_UPDATE:
return Object.assign({}, state, action.payload);
default:
return state;
}
};
Import the StoreModule
@NgModule({
imports: [
// your other imports
StoreModule.provideStore({
settings: settingsReducer
})
]
})
export class AppModule {
//
}
Create Interface for Settings Reducer
export interface SettingsStore {
username: string;
}
Create a Store Interface
export interface AppStore {
settings: SettingsStore;
}
Create Settings Service
@Injectable()
export class SettingsService {
settings$: Observable<SettingsStore>;
constructor(private store: Store<AppStore>) {
this.settings$ = this.store.select('settings');
}
public update(payload) {
this.store.dispatch({ type: SETTINGS_UPDATE, payload });
}
}
Settings Component Controller
@Component({
...
})
export class SettingsComponent implements OnInit {
settings$: Observable<SettingsStore>;
constructor(private settingsService: SettingsService) {
//
}
ngOnInit() {
this.settings$ = this.settingsService.settings$;
}
public updateUsername() {
this.settingsService.update({ username: 'newUsername' });
}
}
Settings Component Template
<p *ngIf="(settings$ | async)?.username">
<strong>Username:</strong>
<span>{{ (settings$ | async)?.username }}</span>
</p>
<button (click)="updateUsername()">Update Username</button>
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 using this.settingsService.update({ ... });
and the change will be reflected on all places which are using that value - be it a component via an async
pipe or another service via .subscribe()
.