Egghead Ngrx/store Video
Source Code
https://github.com/JimTheMan/Jims-Ngrx-Example
Scaffold A New Angular 2 Project
ng new jims-ngrx-eg --skip-git
Install the Ngrx library
npm install @ngrx/core @ngrx/store --save
Give Your State Management Code A Nice Place To Live

Create Your State
export interface State { counter: number; }; export const intitialState: State = { counter: 10 };
Create An Actions Class
export const ActionTypes = { INCREMENT: type('INCREMENT'), }; export class Increment implements Action { type = ActionTypes.INCREMENT; constructor(payload: {someProperty:string, someOtherProperty:boolean}) { } } export type Actions = Increment;
export const ActionTypes = { INCREMENT: type('INCREMENT'), DECREMENT: type('DECREMENT') }; export class Increment implements Action { type = ActionTypes.INCREMENT; constructor(payload: {someProperty:string, someOtherProperty:boolean}) { } } export class Decrement implements Action { type = ActionTypes.DECREMENT; constructor(}) { } } export type Actions = Increment | Decrememnt;
Create Your Reducer
import {ActionReducer, Action} from "@ngrx/store"; import {State, intitialState} from "../state/main-state"; import {INCREMENT, EVENT_FROM_EFFECT} from "../actions/main-action-creator"; export const mainStoreReducer: ActionReducer<State> = (state = intitialState, action: Action) => { console.log('Action came in! ' + action.type); switch (action.type) { case INCREMENT: { console.log('Increment action being handled!'); return { counter: state.counter + 1 } } case EVENT_FROM_EFFECT: { console.log('we cheesin in the reducer over here!'); return { counter: 4 } } default: { return state; } } };
Call ProvideStore In NgModule
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { AppComponent } from './app.component'; import { mainReducer } from "./state-management/reducers/main-reducer"; import { StoreModule } from "@ngrx/store"; @NgModule({ declarations: [ AppComponent ], imports: [ BrowserModule, FormsModule, HttpModule, StoreModule.provideStore({mainReducer}) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
Inject Store Into Your Smart Components
import { Component } from '@angular/core'; import { Store } from "@ngrx/store"; import { State } from "./state-management/state/main-state"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app works!'; constructor (private store:Store<State>) { console.log('We have a store! ' + store); } }
Reading Data From The Store
import { Component } from '@angular/core'; import { Store } from "@ngrx/store"; import { State } from "./state-management/state/main-state"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app works!'; data = ''; constructor (private store:Store<State>) { store.select('mainStoreReducer') .subscribe( (data:State )=> { this.data = 'data is' + data.counter; }); } }
Dispatching An Event To The Store
import { Component } from '@angular/core'; import { Store } from "@ngrx/store"; import { State } from "./state-management/state/main-state"; import { INCREMENT } from "./state-management/actions/main-action-creator"; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'app works!'; data = ''; constructor (private store:Store<State>) { store.select('mainStoreReducer') .subscribe( (data:State )=> { this.data = 'data is' + data.counter; }); this.store.dispatch({ type: INCREMENT }); } }
this.store.dispatch({ type: INCREMENT, payload: {innerObj: {text: "derp!"}} });
console.log('the payload string is: ' + action.payload.innerObj.text);
And That Closes The Loop!
Hungry For Async?
Update: You can check out the Part 2 post about async with ngrx/effects here!