Slide 1

Slide 1 text

Managing State In Angular with Redux Thursday January 11, 2018 Doug Corbett [email protected]

Slide 2

Slide 2 text

Basic State Management in Angular 1 Anatomy of a Redux Implementation 3 Final Thoughts 4 Basic Redux Ideas 2 Agenda

Slide 3

Slide 3 text

on Basic State Management in Angular

Slide 4

Slide 4 text

Component State (DOM) Parent Component Child Component Grandchild Component (Property binding) (Event binding) * Reactive Forms

Slide 5

Slide 5 text

Demo

Slide 6

Slide 6 text

Singleton Services authService currentUser firstName lastName permissions isAdmin browsingHistory orderService orderList productList currentOrders productList cartService productList currentItem productService productList currentProduct featuredProducts trendingProducts bestSellingToys moviesOnSale bestSellingBooks reccomendedProducts

Slide 7

Slide 7 text

Singleton Services pmtMethodService pmtMethodList defaultMethod featuredProducts trendingProducts bestSellingToys moviesOnSale bestSellingBooks reccomendedProducts membershipService profileService messagingService rentalService deviceMgmtService videoService authService currentUser firstName lastName permissions isAdmin browsingHistory orderService orderList productList currentOrders productList cartService productList currentItem productService productList currentProduct featuredProducts trendingProducts bestSellingToys moviesOnSale bestSellingBooks reccomendedProducts

Slide 8

Slide 8 text

Demo

Slide 9

Slide 9 text

Redux • Data Architecture Pattern • Characteristics • Centralized State Management • Immutability • Pub/Sub communication between State Store and listening components

Slide 10

Slide 10 text

on Basic Redux Ideas

Slide 11

Slide 11 text

Why? • More complex apps become easier to work with using centralized state. • Property binding between parent and child components can run into problems with larger applications. • Hard to get a picture of the entire application’s state without centralized state. • Developers have one place to look for state instead of components and services. • Undo/Redo • Testability

Slide 12

Slide 12 text

Centralized State Management • Can view the state of the entire application easily • Changes to state happen in one place • Changes to the state can be subscribed to and unsubscribed from so dependent component can react to state changes efficiently.

Slide 13

Slide 13 text

Immutability • The practice of not modifying values in memory directly, but creating new values in memory and changing a variable to point to the new location. • Avoid side effects • Fast • Makes multi threaded apps safer by avoiding locking and race conditions • Increased Garbage Collector processing and memory usage

Slide 14

Slide 14 text

Pub/Sub Communication • Loose coupling • Efficient communication between dispatchers and subscribers

Slide 15

Slide 15 text

on Anatomy of a Redux Implementation

Slide 16

Slide 16 text

Redux Elements • Action • Reducer • State Reducer State Action

Slide 17

Slide 17 text

State • An interface that represents the structure of the state of the application that needs to be available to the entire application. export interface AppState { currentUser: UserProfile, recentlyViewedProducts: Array, cart: Array }

Slide 18

Slide 18 text

Action • Objects that represent some kind of action in the system. It is comprised of two parts, an action identifier and, optionally, a payload. { type: ‘ADD_PRODUCT_TO_CART’, product: { “title’: “Girls bicycle”, “description”: “Two wheels and ribbons”, “quantity”: 100 } }

Slide 19

Slide 19 text

Reducer • A reducer takes an action and the old state and returns a new state. • It does not change state directly. • It is a “pure function”, meaning that based on the same input, it returns the same output without side effect. import { ADD_PRODUCT_TO_CART } from ‘./cart.actions’ const initialState: AppState = { cart: [] } export const cartReducer: Reducer = (state: AppState = initialState, action: Action): AppState => { switch(action.type) { case ‘ADD_PRODUCT_TO_CART’: return { Object.assign({}, state, { cart: state.cart.concat( (action).product; ) } } default: return state; } }

Slide 20

Slide 20 text

Redux Elements • Action • Reducer • State • Store • Component Reducer Action Component Action (string) Data (object) Store State

Slide 21

Slide 21 text

Triggering Components • These are the components that intend to indirectly change state. They do this by dispatching an Action Object to the Store. store.dispatch({ type: ‘ADD_PRODUCT_TO_CART’, product: { “title’: “Girls bicycle”, “description”: “Two wheels and ribbons”, “quantity”: 100 } } as AddProductAction);

Slide 22

Slide 22 text

Store • Object responsible for persisting and changing state. // app.store.ts let store: Store == createStore(cartReducer); export const AppStore = new InjectionToken(‘App.store’); const devtools: StoreEnhancer = window[‘devToolsExtension’] ? window[‘devToolsExtension’]() : f => f; … export createAppStore(): Store { return createStore( reducer, compose(devtools) ); } export const appStoreProviders = [ { provide: AppStore, useFactory: createAppStore } ];

Slide 23

Slide 23 text

Redux Elements • Action • Reducer • State • Store • Component • Action Creator • Observer Reducer Component Store State Action Creator Action Action (string) Data (object) Observer

Slide 24

Slide 24 text

Action Creators • This is an optional convenience helper object that takes a payload and creates an action class with an internally specified action and provided payload. • This is not specifically required, but leverages strong typing to eliminate typing defects and improves code readability. // cart.actions.ts import { Action, ActionCreator } from ‘redux’ export const ADD_PRODUCT_TO_CART: string ‘ADD_PRODUCT_TO_CART’; export const addProductToCart: ActionCreator = (product) => ( { type: ADD_PRODUCT_TO_CART, product: product } );

Slide 25

Slide 25 text

Observers • Any component that subscribes to state changes constructor(@Inject(AppStore) private store: Store) { store.subscribe(() => this.updateState()); this.updateState(); } updateState() { // getUnreadMessagesCount is a selector function this.unreadMessagesCount = getUnreadMessagesCount(this.store.getState()); }

Slide 26

Slide 26 text

Other Concepts • rootReducer – every app has one starting reducer and it may possibly have sub reducers below that. • State Slices – a way of grouping related reducers, actions and state away from those unrelated.

Slide 27

Slide 27 text

Final Thoughts

Slide 28

Slide 28 text

Final Thoughts • The Redux pattern takes some getting used to. • Redux is designed to make things easier for large projects but at a cost. • Redux emerged out of the React ecosystem and you are likely to encounter it. • Once you internalize the pattern, it simplifies the burden of managing state

Slide 29

Slide 29 text

Reference Materials Official Angular Documentation https://angular.io Build Enterprise Applications with Angular 2 (and Angular 4) – Mosh Hamedani https://www.udemy.com/angular2-advanced Using Redux to Manage State in Angular - Hendrik Swanepoel https://app.pluralsight.com/library/courses/angular-2-redux-manage-state Advanced Redux - Daniel Stern https://app.pluralsight.com/library/courses/advanced-redux Building a Redux application with Angular 2 – Parts 1 and 2 - Hristo Georgiev https://www.pluralsight.com/guides/front-end-javascript/building-a-redux-application-with-angular-2-part-1 https://www.pluralsight.com/guides/front-end-javascript/building-a-redux-application-with-angular-2-part-2 ng-book – The Complete Book on Angular 4 – Nathan Murray and Ari Lerner Angular Redux Demo code https://github.com/dougcorbett/angular-redux-demo