It's assumed that you are already familiar with Redux ecosystem. If not click an image below:
Angular-redux/store
We have installed @angular-redux/store which integrates our redux store in Ng2 applications.
npm install redux @angular-redux/store --save
Store:
Here we create the simple possible store with typed state and one field marker
,
that will be updated with each action.
import { combineReducers } from 'redux';
import {ItemsState, itemsReducer} from './items/items.reducer';
/**
* Our Application state
*
* @interface IAppState
*/
export interface IAppState {
readonly marker?: String
}
/**
* Root reducer of our app
*/
export const rootReducer = combineReducers<IAppState>({
marker: marker
});
/**
* Our inlined sub-reducer for updating the marker.
*/
function marker(state:String = "InitialEmptyState", action: any): String {
return "MarkedByAction " + action.type;
}
Component:
Our Component in which we will display our marker field changes.
import { Component } from '@angular/core';
import {NgRedux, select} from '@angular-redux/store';
import {Observable} from 'rxjs';
import {IAppState} from '../store/store';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
constructor(private ngRedux: NgRedux<IAppState>, private actions: AppActions) { }
ngOnInit() { }
public clickHandler(): void {
this.ngRedux.dispatch(this.actions.create());
}
}
So, whenever the clickHandler
is invoked we dispatch some action which updates our marker
state.
Get updates from Store
To update the UI we need to subscribe
on our state updates and here are the various ways to do so.
*Note: To focus on the receiving state updates, we will just output values into the log.
Also for an explicit difference between variables, all variable names are different. Otherwise I would stick to just marker$
for streams.
Subscribe for all State changes
This is the most primitive way. We subscribe for the all changes and retrieve needed field from the whole State:
constructor(private ngRedux: NgRedux<IAppState>, private actions: ItemsActions) {
ngRedux.subscribe(() => {
console.log("State Changed! m: " + this.ngRedux.getState().marker);
});
}
Select property from NgRedux store as an Observable
Below is three different ways which do exact the same thing.
-
Select with Fat Arrow
TypeScriptngOnInit() { const stream1$ = this.ngRedux.select(state => state.marker); stream1$.subscribe(m => { console.log("#1 Marker updated! m: " + m); }); }
-
Select with Selector.
Separating your selector migh become handy if you have a deep structure and need to be able to reuse selector in different places.* marker.selector.ts
TypeScriptimport {IAppState} from '../store'; /** * Selector for 'marker' in application store */ export const markerSelector = (state: IAppState) => state.marker;
* app.component.ts
TypeScriptimport {markerSelector} from '../store/marker.selector'; ... ngOnInit() { const stream2$ = this.ngRedux.select(markerSelector); stream2$.subscribe(m => { console.log("#2 Marker updated! m: " + m); }); }
-
Select by property Name.
TypeScriptngOnInit() { const stream3$ = this.ngRedux.select('marker'); stream3$.subscribe(m => { console.log("#3 Marker updated! m: " + m); }); }
If you have a deeper structure pass it as an array
TypeScriptconst bar$ = this.ngRedux.select(['foo', 'bar']);
-
Select via
@select
annotation.TypeScript@select(['marker']) readonly stream4$: Observable<string>; ... ngOnInit() { this.stream4$.subscribe(m => { console.log("#4 Marker updated! m: " + m); }); }
Display Updates in UI
Here are also few ways to display your updates in UI:
-
Update property in subscribe handler
* app.component.html
<h2>Marker: {{marker}}</h2>
* app.component.ts
TypeScriptpublic marker: string; ... ngOnInit() { const marker$ = this.ngRedux.select<string>('marker'); marker$.subscribe(newMarker => this.marker = newMarker); }
-
Use
| async
pipe in template.
It will automatically subscribe to yourObservale
stream and retrieve the values.* app.component.html
<h2>Marker: {{marker$ | async}}</h2>
* app.component.ts
TypeScript@select(['marker']) readonly marker$: Observable<string>;
Conclusions
- Use the
@selector
annotation withreadonly
access modifier - Bind UI directly with Observable property through
| async
pipe - Use Types everywhere.
Thank you for sharing good information
ReplyDeleteFull Stack online Training
Full Stack Training
Full Stack Developer Online Training
This post will be very useful to us....i like your blog and helpful to me....nice thoughts for your great work....
ReplyDeleteDedicated Angularjs Developer in India