yet another state management Angular library

Michał Michalczuk

michalczukm.xyz

This speech is about

NGXS and its features

not about state management in general

        as pattern

        with effects

        implementations in

Michał Michalczuk

Senior JavaScript Developer

Ciklum / Stibo Systems

 

 

IT trainer

infoShare Academy

 

yet another state management Angular library

Michał Michalczuk

michalczukm.xyz

 

NGXS is a state management pattern + library for Angular.

       ...

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.

What

can do?

More or less
everything as

but ...

In more OOP way

Without lot of boilerplate

 

And few things more - wait for it

 

With lot of decorators

 

Install it

// dependencies
"@ngxs/store": "^3.4.3",

// devDependencies
"@ngxs/devtools-plugin": "^3.4.3",
// dependencies
"@ngrx/effects": "^7.4.0",
"@ngrx/store": "^7.4.0",

// devDependencies
"@ngrx/store-devtools": "^7.4.0",

Plug it

@NgModule({
  imports: [
    ...
    NgxsModule.forRoot([CartState]),
    NgxsReduxDevtoolsPluginModule.forRoot({
      disabled: environment.production,
      maxAge: 25
    })
  ],
})
export class AppModule {}
@NgModule({
  imports: [
    ...
    StoreModule.forRoot(reducers),
    EffectsModule.forRoot([]),
    AppRoutingModule,
    StoreDevtoolsModule.instrument({
      maxAge: 25,
      logOnly: environment.production
    })  
  ],
})
export class AppModule {}

Setup

// store/index.ts
export interface RootStore {
  cart: CartStore;
}

export const reducers: ActionReducerMap<RootStore> = {
  cart,
};

export * from './cart.reducer';


// cart.reducer.ts
const initialState = {
  stickers: [] as Sticker[],
  tshirts: [] as Tshirt[]
} as CartStore;

export interface CartStore {
  stickers: Sticker[];
  tshirts: Tshirt[];
}

Setup

export class StickerAddAction implements Action {
  type = 'STICKER_ADD';
  constructor(public payload: Sticker) {}
}


export const cart = (state = initialState, action: CartActions): 
  CartStore => 
{
  switch (action.type as string) {
    case 'STICKER_ADD':
      return {
        ...state,
        stickers: [
            ...state.stickers, 
            {...action.payload}
        ]
      };
    default:
      return state;
  }
};

Setup

// cart.state.ts

export interface CartStateModel {
  stickers: Sticker[];
  tshirts: Tshirt[];
}

export class AddSticker {
  static readonly type = '[cart] add sticker';
  constructor(public payload: Sticker) {}
}

Setup

@State<CartStateModel>({
  name: 'cart',
  defaults: {
    stickers: [] as Sticker[],
    tshirts: [] as Tshirt[]
  }
})
export class CartState {
  @Action(AddSticker)
  addSticker({ patchState, getState }: StateContext<CartStateModel>, 
             { payload }: AddSticker): void 
{
    const state = getState();

    patchState({
      stickers: [
        ...state.stickers,
        payload
      ]
    });
  }
}

What else?

Snapshot

When you need synchronous access to store data

Snapshot

const currentStickers: Sticker[] = 
    this.store.selectSnapshot(state => state.stickers.stickers);

Anywhere in your app

Mini life cycle

import { ..., NgxsOnInit } from '@ngxs/store';


@State<StickersStateModel>({ ... }})
export class StickersState implements NgxsOnInit {

  ngxsOnInit(context?: StateContext<StickersState>) {
    if (context) {
      ctx.dispatch(new FetchStickers());
    }
  }

  ...
}

ofAction

import { Store, Actions, ofActionSuccessful } from '@ngxs/store';


export class AppComponent implements OnInit, OnDestroy {

  constructor(private store: Store,
    private actions: Actions) {
  }

  ngOnInit(): void {
    this.actions
      .pipe(
        ofActionSuccessful(AddSticker)
      )
      .subscribe(
        (action: AddSticker) => console.log(
            `${action.payload.name} sticker bought!`
           )
      );
  }

  ...

}

Plugins

plugins = official

Labs

labs = experimental

Who uses

When to use

So ... is it like this?

Angular

Devs

Or ... like this?

Angular

Devs

Angular

Devs

For sure this is true

Statefull
components

Angular

Devs

Questions time

Feedback?

Yes please

Michał Michalczuk

michalczukm.xyz

Thank you!

michalczukm

Made with Slides.com