Skip to content
On this page

5.Using State Management Plugin and devTool

Using @ngxs/store to manege the State

To use @ngxs/store in an Angular application, you need to follow these steps:

  1. Install the necessary package:

    sh
    npm install @ngxs/store
  2. Import the required modules in your application's root module (app.module.ts):

    typescript
    import { NgxsModule } from '@ngxs/store';
    import { CounterState } from './counter.state'
    
    @NgModule({
      imports: [
        // ...
        NgxsModule.forRoot([CounterState]) // Specify your initial state classes here
      ],
      // ...
    })
    export class AppModule {}
  3. Define your state classes. A state class represents a piece of the application state and includes its properties, actions, and selectors. For example:

    ts
    // counter.actions.ts
    
     export class Increment {
         static readonly type = '[Counter] Increment';
     }
    
     export class Decrement {
         static readonly type = '[Counter] Decrement';
     }
    
     export class Reset {
         static readonly type = '[Counter] Reset';
     }
    typescript
    import { State, Action, StateContext, Selector } from '@ngxs/store';
    import { Increment, Decrement } from './counter.actions'
    
    // Define your state model interface
    interface CounterStateModel {
      count: number;
    }
    
    // Define your state class
    @State<CounterStateModel>({
      name: 'counter',
      defaults: { count: 0 }
    })
    export class CounterState {
      // Define actions that can be dispatched to modify the state
      @Action(Increment)
      increment(ctx: StateContext<CounterStateModel>) {
        const state = ctx.getState();
        ctx.setState({ count: state.count + 1 });
      }
    
      // Define selectors to retrieve specific portions of the state
      @Selector()
      static getCount(state: CounterStateModel) {
        return state.count;
      }
    }
  4. Use the state in your components by dispatching actions and accessing state properties through selectors. For example:

    typescript
    import { Component } from '@angular/core';
    import { Store, Select } from '@ngxs/store';
    import { Increment } from './counter.actions';
    
    @Component({
      // ...
    })
    export class MyComponent {
      @Select(CounterState.getCount) count$: Observable<number>;
    
      constructor(private store: Store) {}
    
      increment() {
        this.store.dispatch(new Increment());
      }
    }
  5. Render it to the html template

html
<!-- my-component.component.html -->

    <h1>Count: {{ count$ | async }}</h1>

    <button (click)="increment()">Increment</button>

In this example, the CounterState class represents the state of a counter feature. It defines an action Increment that increases the count by one and a selector getCount to retrieve the count value. In the component, the count$ observable is used to subscribe to changes in the count value, and the increment() method dispatches the Increment action.

Using @ngxs/router-plugin to manage router state

To use the @ngxs/router-plugin in an Angular application with NGXS, you need to follow these steps:

  1. Install the necessary packages:

    shell
    $ npm install @ngxs/store @ngxs/router-plugin
  2. Import the required modules in your application's root module (app.module.ts):

    typescript
    import { NgxsModule } from '@ngxs/store';
    import { NgxsRouterPluginModule } from '@ngxs/router-plugin';
    import { CounterState } from './counter.state'
    @NgModule({
      imports: [
        // ...
        NgxsModule.forRoot([CounterState]),
        NgxsRouterPluginModule.forRoot()
      ],
      // ...
    })
    export class AppModule {}
  3. Define the state classes for your router-related state. This typically involves creating a state class for the router state and extending it from @ngxs/router-plugin's RouterStateModel class:

    typescript
    import { RouterStateModel, RouterState } from '@ngxs/router-plugin';
    
    export class AppStateModel {
      // ... your other state properties
      router: RouterStateModel;
    }
    
    @State<AppStateModel>({
      name: 'app',
      defaults: {
        // ... your other state defaults
        router: {
          state: {},
          navigationId: 0
        }
      }
    })
    export class AppState {
      @Selector()
      static routerState(state: AppStateModel): RouterStateModel {
        return state.router;
      }
    }
  4. In your component templates or code, you can use the routerState selector to access the router state and perform actions or display information based on the current route. For example:

    typescript
    import { Select } from '@ngxs/store';
    import { RouterStateModel, Navigate } from '@ngxs/router-plugin';
    
    @Component({
      // ...
    })
    export class MyComponent {
      @Select(AppState.routerState) routerState$: Observable<RouterStateModel>;
    
      constructor(private store: Store) {}
    
      // Example method that triggers navigation
      navigateToHome() {
        this.store.dispatch(new Navigate(['/home']));
      }
    }

These are the basic steps to get started with @ngxs/router-plugin. The plugin integrates NGXS with the Angular router, allowing you to manage routing-related state and perform navigation actions from your NGXS state and components.