Slide 1

Slide 1 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Overview of Angular State Management Tools Version 1.0, 13.03.2019

Slide 2

Slide 2 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Interact with data (loading, manipulating) Display data in a component Process data on the client 03 01 02 What is state management?

Slide 3

Slide 3 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf

Slide 4

Slide 4 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Redux’s key ideas ● All of your application’s data is in a single data structure called the state which is held in the store. ● Your app reads the state from this store. ● The state is never mutated directly outside the store. ● The views emit actions that describe what happened. ● A new state is created by combining the old state and the action by a function called the reducer.

Slide 5

Slide 5 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf

Slide 6

Slide 6 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Why you might not need explicit state management ● Global state ● Little shared state (between components) ● Little mutable state ● Little complexity ● Stateful services work ● No increase of your dependencies ● Because I’m talking about it

Slide 7

Slide 7 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Why you can benefit from explicit state management ● Single source of truth ● Simplify deep component interaction ● Consistent programming architecture and style ● Improved debuggability ● Persistence of state (local-storage)

Slide 8

Slide 8 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Overview of state management tools ● Plain RxJs ● NgRx ● NGXS ● Akita

Slide 9

Slide 9 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Plain RxJs ● Stateful Angular services with BehaviorSubject ● Simple and easy way to define a state ● Observable with multiple subscribers ○ Get notifications for every change ○ Get current state (last value) ● Difficult to handle dependencies between states

Slide 10

Slide 10 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf export class AppComponent { constructor(private numberService: NumberService) { console.log('current value: ' + numberService.getValue()); numberService.subscribe('subscriberA'); numberService.next(1); numberService.subscribe('subscriberB'); numberService.next(2); console.log('current value: ' + numberService.getValue()); } } export class NumberService { subject = new BehaviorSubject(0); subscribe(subscriber: string): void { this.subject.subscribe((value: number) => console.log(subscriber, value)); } next(value: number): void { console.log('executing next with value ', value); this.subject.next(value); } getValue(): number { return this.subject.value; } } Output: 01: current value: 0 02: subscriberA 0 03: executing next with value 1 04: subscriberA 1 05: subscriberB 1 06: executing next with value 2 07: subscriberA 2 08: subscriberB 2 09: current value: 2

Slide 11

Slide 11 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Plain RxJs conclusion ● (+) No dependencies ● (+) Adaptable to your specific needs ● (+) Good for small projects ● (+) Only those functions that you need, no boilerplate ● (-) Hard to achieve consistent stateful services in the codebase ● (-) No debug support ● (-) Take care of duplicated logic across services ● (-) No out of the box support for local storage of state

Slide 12

Slide 12 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf NgRx ● State is a single, immutable data structure. ● Components delegate responsibilities to side effects. ● Actions and state are serializable to ensure state is predictably stored, rehydrated, and replayed. ● Promotes the use of functional programming when building reactive applications. ● NgRx provides Effects for decoupling actions and reducers.

Slide 13

Slide 13 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf

Slide 14

Slide 14 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf NgRx conclusion ● (+) Popular framework with active development ● (+) DevTools ● (+) Support for @angular schematics ● (+) Effects (decoupling actions from reducer functions) ● (-) Verbosity/complexity ● (-) Offline persistency only with 3rd party library

Slide 15

Slide 15 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf NGXS «NGXS is modeled after the CQRS pattern popularly implemented in libraries like Redux and NGRX but reduces boilerplate by using modern TypeScript features such as classes and decorators.»

Slide 16

Slide 16 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf export class SetNumberAction { static readonly type = '[App] Set number'; constructor(public activeNumber: number) {} } export class AppStateModel { activeNumber: number; @State({ name: 'app', defaults: { activeNumber: 0 } }) export class AppState { @Action(SetNumberAction) setNumber(ctx: StateContext, action: SetNumberAction) { ctx.setState({activeNumber: action.activeNumber}); } }

Slide 17

Slide 17 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf @Component({ selector: 'app-number', template: `

Number: {{activeNumber$ | async}}

` }) export class NumberComponent { @Select(state => state.app.activeNumber) activeNumber$: Observable; constructor(private store: Store) {} numberChange(activeNumber: number) { this.store.dispatch(new SetNumberAction(activeNumber)) } }

Slide 18

Slide 18 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf NGXS conclusion ● (+) DevTools ● (+) boilerplate-less version of NgRx ● (+) annotations instead of switch case in the reducer ● (+) Popular framework with active development ● (-) Not as widely adopted as NgRx (yet) ● (-) Reducers are not pure functions

Slide 19

Slide 19 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Akita «Akita is a state management pattern, built on top of RxJS, which takes the idea of multiple data stores and immutable updates, along with the concept of streaming data, to create the Observable Data Store model.»

Slide 20

Slide 20 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Akita https://medium.com/codingthesmartway-com-blog/learn-redux-introduction-to-state-management-with-react-b87bc570b12a

Slide 21

Slide 21 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf @Component({ selector: 'app-number', template: `

Number: {{activeNumber$ | async}}

` }) export class AppComponent { activeNumber$: Observable = this.numberQuery.activeNumber$; constructor(private numberQuery: NumberQuery, private numberStore: NumberStore) {} numberChange(activeNumber: number) { this.numberStore.update({activeNumber}); } }

Slide 22

Slide 22 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf export interface NumberState { activeNumber: number; } export function createInitialState(): NumberState { return { activeNumber: 0 }; } @StoreConfig({name: 'number'}) export class NumberStore extends Store { constructor() { super(createInitialState()); } } export class NumberQuery extends Query { activeNumber$ = this.select(state => state.activeNumber); constructor(protected store: NumberStore) { super(store); } }

Slide 23

Slide 23 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Akita conclusion ● (+) DevTools ● (+) EntityStore and EntityQuery ● (+) Logic of querying store in Query class ● (+) Can be used together with Angular, React, Vue.js ● (+) Boilerplate-free ● (+/-) Not built on top of Redux ● (-) Not as widely used as its competitors ● (-) ui state vs data state

Slide 24

Slide 24 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Key takeaways ● Create a plan regarding state management upfront. ● Experiment with a state management library in a small project. ● Experiment with RxJs (BehaviorSubject) in a large project. ● Be aware of the benefits and drawbacks of explicit state management frameworks. ● Local state is perfectly fine.

Slide 25

Slide 25 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Local state is perfectly fine.

Slide 26

Slide 26 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf

Slide 27

Slide 27 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf nxt Engineering GmbH [email protected] Alte Gfennstrasse 72 CH-8600 Dübendorf Mirco Widmer Senior Software Engineer @mircowidmer [email protected]

Slide 28

Slide 28 text

nxt Engineering GmbH [email protected] https://nxt.engineering +41 44 508 52 45 Alte Gfennstrasse 72 CH-8600 Dübendorf Further information ● You Might Not Need Redux ● Intro to Flux and Redux ● Understanding rxjs BehaviorSubject, ReplaySubject and AsyncSubject ● Angular: NGRX a clean and clear Introduction ● Angular state management comparison ● nxt Engineering