Redux & Angular2

Part 1

Redux in short

"Redux is a predictable state container for JavaScript apps.

 

It helps you write applications that behave consistently, run in different environments (client, server, and native), and are easy to test. On top of that, it provides a great developer experience, such as live code editing combined with a time traveling debugger."

 

from reactjs/redux repo

Store

Store will store your application state.
The Store is king of the "database" of client side. it's the 'single source of truth' and can be queried from any place of the application.

 

snapshot of store at any point will supply a complete representation of relevant application state.

Reducers

Pure functions that takes 2 params:

  1. Current state
  2. Action (with optional payload

Reducer function will return a new state object

// Action interface
export interface Action {
  type: string;
  payload?: any;
}

Centralized, Immutable State

Dispatched Action Pipeline

Code time

EventReducer

  • cd src/app
    mkdir reducers && cd reducers
    touch events.reducer.ts
     
  • import Action:


     
  • Define Actions constants (export for future import):




     
import { Action } from '@ngrx/store';
export const GET_EVENTS = 'GET_EVENTS';
export const GET_EVENTS_SUCCESS = 'GET_EVENTS_SUCCESS';
export const ADD_EVENTS = 'ADD_EVENTS';

EventReducer

  • Define our Events State interface:




     
  • Define the initial state params:
const initialState: EventsState = {
  events: [],
  loading: false,
  ...
};
export interface EventsState {
  events: any;
  loading: boolean;
  ...
}

EventReducer

  • Define the reducer and add logic:
export const eventsReducer = (state = initialState, action: Action): EventsState => {
  switch (action.type) {
    case GET_EVENTS:
      return Object.assign({}, state, {
        loading: true
      });
    case GET_EVENTS_SUCCESS:
      return Object.assign({}, state, {
        loading: false
      });
    case ADD_EVENTS:
      return Object.assign({}, state, {
        events: state.events.concat(action.payload)
      });
    ....
    default:
      return state;
  }
}

Register the store in app bootstrap 

  • Import 'store' and 'store-devtools':



     
  • Open src/main.ts and add providers for the store and for redux devtools:
bootstrap(AppComponent, [
  ...
  provideStore({ events: eventsReducer }),
  instrumentStore(),
  ...
]);
import { provideStore } from '@ngrx/store';
import { instrumentStore } from '@ngrx/store-devtools';

Dispatch from component

  • Import Store and actions constants from reducer:


     
  • Modify constructor to include store:


     
  • Dispatch action from a function:
import { Store } from '@ngrx/store';
import { GET_EVENTS, GET_EVENTS_SUCCESS, ADD_EVENTS } from '../reducers/events.reducer';
constructor(public store: Store<any>, ...)
getEvents(start: number, end: number) {
    this.store.dispatch({ type: GET_EVENTS });
    this.eventsService.getEvents(start, end)
      .subscribe(res => {
        this.store.dispatch({ type: GET_EVENTS_SUCCESS });
        this.store.dispatch({ type: ADD_EVENTS, payload: res.data.map(event => new EventModel(event)) });
      });
  }

Getting data from Store in a component

  • Use the 'select' function on the store
  • Get Events state data
  • Subscribe for changes
  • Bind data to the class members for view usage
constructor(public store: Store<any>, ...) {
    store.select(s => s.events).subscribe(eventsState => {
      this.events = eventsState.events;
      this.loading = eventsState.loading;
      ...
    });
}

Redux DevTools

Open installed chrome extension 'Redux Devtools' and see the actions goes in.

Homework

  • Get the static template of event route from '_templates/event.html' and get it into the app
    • Bind the data
    • Make use of existing components for reuse
    • Make new components if needed
  • Implement 'CHANGE_RSVP_STATE' action function in eventsReducer  and dispatch this action from 'EventRsvpToggleBtnComponent'
  • Play around with 'redux devtools' chrome extension to test the redux implementation you added

 

 

Need help?
https://gitter.im/dvh91/kmeetups

ngrx-store-01

By Dvir Hazout

ngrx-store-01

  • 833