Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Overview of Angular State Management Tools

Overview of Angular State Management Tools

State management is challenging. Complex web applications contain a lot of state and it’s necessary to update this state correctly in order to have a product that works exactly as it is supposed to. In this talk I would like to give you an overview of the current techniques and frameworks to handle state management in the Angular context. This covers Plain RxJs, NGRX, NGXS and Akita.

Mirco Widmer

March 18, 2019
Tweet

Other Decks in Technology

Transcript

  1. 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
  2. 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?
  3. 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.
  4. 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
  5. 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)
  6. 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
  7. 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
  8. 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<number>(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
  9. 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
  10. 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.
  11. 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
  12. 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.»
  13. 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<AppStateModel>({ name: 'app', defaults: { activeNumber: 0 } }) export class AppState { @Action(SetNumberAction) setNumber(ctx: StateContext<AppStateModel>, action: SetNumberAction) { ctx.setState({activeNumber: action.activeNumber}); } }
  14. 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: ` <input type="number" (keyup)="numberChange($event.target.value)"> <h1>Number: {{activeNumber$ | async}}</h1> ` }) export class NumberComponent { @Select(state => state.app.activeNumber) activeNumber$: Observable<number>; constructor(private store: Store) {} numberChange(activeNumber: number) { this.store.dispatch(new SetNumberAction(activeNumber)) } }
  15. 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
  16. 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.»
  17. 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
  18. 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: ` <input type="number" (keyup)="numberChange($event.target.value)"> <h1>Number: {{activeNumber$ | async}}</h1> ` }) export class AppComponent { activeNumber$: Observable<number> = this.numberQuery.activeNumber$; constructor(private numberQuery: NumberQuery, private numberStore: NumberStore) {} numberChange(activeNumber: number) { this.numberStore.update({activeNumber}); } }
  19. 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<NumberState> { constructor() { super(createInitialState()); } } export class NumberQuery extends Query<NumberState> { activeNumber$ = this.select(state => state.activeNumber); constructor(protected store: NumberStore) { super(store); } }
  20. 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
  21. 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.
  22. 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.
  23. 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]
  24. 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