Akita

A state management pattern

Thomas Vanhoutte

Frontend developer

Technology stack

Technology stack

State management

How does it work?

  • Server response data

  • User information

  • User input

  • UI state

  • Router/location state

Let's start with application state

  • Model our app state

  • Update state

  • Read state values

  • Monitor/observe changes to state

State management libraries

import {State} from '@ngxs/store';
import {Branch, Company, WsplItem} from '@psp/entities';
import {User} from '../modules/common/types/user';

export interface AppStateModel {
  companyAndBranch: {
    company: Company;
    branch: Branch;
  };
  pspItems: Array<WsplItem>;
  selectedWsplItem: WsplItem;
  pspItemsFilter: any;
  wsplScrollPosition: number;
  profile: {user: User; loggedIn: boolean; language: {code: string; text: string};};
}

const initialState: AppStateModel = {
  companyAndBranch: undefined,
  pspItems: undefined,
  selectedWsplItem: undefined,
  pspItemsFilter: undefined,
  wsplScrollPosition: undefined,
  profile: undefined
};

@State<AppStateModel>({
  name: 'app',
  defaults: initialState
})
export class AppState {}
  • Single source of truth

  • State is read-only

  • Pure functions

  • Single state tree

  • Actions

  • Reducers

  • Store

  • One-way dataflow

VS

VS

  • Rxjs, Flux and Redux

  • Simplicity

  • Boilerplate-free code

  • For everyone to use

  • OOP

  • Opinionated

Updates

Streaming Data

Rendering

Actions (methods)

Interacting with other queries

  • Single source of truth

  • setState()

  • Usage of Query

  • Asynchronous logic

Model

import { ID } from '@datorama/akita';

export type Todo = {
  id: ID;
  title: string;
  completed: boolean;
};

export function createTodo({ id, title }: Partial<Todo>) {
  return {
    id,
    title,
    completed: false
  } as Todo;
}

Entity Store

import { Todo } from './todo.model';
import { EntityState, EntityStore } from '@datorama/akita';

export interface State extends EntityState<Todo> {}

@Injectable({
  providedIn: 'root'
})
export class TodosStore extends EntityStore<State, Todo> {
  constructor() {
    super(initialState);
  }
}

Entity Query

import { QueryEntity } from '@datorama/akita';

@Injectable({
  providedIn: 'root'
})
export class TodosQuery extends QueryEntity<State, Todo> {
  constructor(protected store: TodosStore) {
    super(store);
  }
}
ng new angular-akita-thomasvht
yarn add @datorama/akita
yarn add akita/schematics -D
yarn add @datorama/akita-ngdevtools -D
  • Reactive applications

  • State management

  • Isolation of side effects

  • Entity collection management

  • Router bindings

  • Code generation

  • Developer tools

  • State is a single, immutable data structure.

  • Components delegate responsibilities to side effects.

  • Type-safety with Typescript.

  • Actions and state are serializable.

  • Functional programming.

  • Straightforward testing strategies.

import { Action } from '@ngrx/store';
 
export enum ActionTypes {
  Increment = '[Counter Component] Increment',
  Decrement = '[Counter Component] Decrement',
  Reset = '[Counter Component] Reset',
}
 
export class Increment implements Action {
  readonly type = ActionTypes.Increment;
}
 
export class Decrement implements Action {
  readonly type = ActionTypes.Decrement;
}
 
export class Reset implements Action {
  readonly type = ActionTypes.Reset;
}
import { Action } from '@ngrx/store';
import { ActionTypes } from './counter.actions';
 
export const initialState = 0;
 
export function counterReducer(state = initialState, action: Action) {
  switch (action.type) {
    case ActionTypes.Increment:
      return state + 1;
 
    case ActionTypes.Decrement:
      return state - 1;
 
    case ActionTypes.Reset:
      return 0;
 
    default:
      return state;
  }
}
ng new angular-ngrx-thomasvht
yarn add @ngrx/platform
yarn add @ngrx/devtools -D
yarn add @ngrx/schematics -D
  • Statemanagement + library for Angular

  • Single source of truth

  • Simple rules

  • CQRS

  • Reduces boilerplate

  • Classes and decorators

  • Store

  • Actions

  • State

  • Selects

ng new angular-ngxs-thomasvht
yarn add @ngxs/store
yarn add @ngxs/devtools -D
yarn add @ngxs/schematics -D

Which one to choose?

 Tooling          Redux devtools             Schematics

  Boilerplate

Files generated

Total files

Boilerplate code

9

3

4

12

7

6

Heavy

Medium

Low

1

2

3

Community

1

2

3

1 (4779)

2 (2192)

3 (1290)

1 (186)

2 (105)

3 (24)

1 (753)

2 (1111)

3 (528)

Community

7.9

313

8.7

380.6

8.8

393.0

9

411.9

Size

Non-prod (Mb)

Prod (Kb)

Our choice

IT Talks

By Thomas Vanhoutte

IT Talks

  • 1,217