top of page

Introduction to NGXS, state management pattern + library for Angular



Ngxs is a state management pattern for the Angular framework. It acts as a single source of truth for our application. Ngxs is very simple and easily implementable. It reduce lots of boilerplate code . It is a replacement for Ngrx. In Ngrx we are creating state, action, reducer, and effects but in Ngxs, we are creating only state and actions instead of all of this. Like Ngrx, Ngxs is also asynchronous and when we dispatch any action we can get a response back.


When we learn anything then one Question always arrives in our mind.


Why do we use NGXS?

NGXS tries to make things as simple and accessible as possible. There can be a lot of boilerplate code in state management, thus a main goal of NGXS is to reduce boilerplate allowing you to do more things with less. It is also not necessary to be super familiar with RxJs.


Dependency injection is a core feature of Angular. We create a single instance of a class that gives better performance and many more things. Ngsx allows us to use DI. We can create a singleton instance and use it everywhere.


Promises:

Observables are good but they are not silver bullets. Sometimes we need to use promises. Ngxs allow us to return from the Action method.



Pillars of Ngxs:

Ngxs has 4 pillars in which ngxs work

  1. Store: Global state container

  2. Action: classes that describe actions and metadata

  3. State: state is the definition of class

  4. Selects: selectors slices state

Let us learn every pillar one by one:


Install dependencies :

  • run command ng add @ngxs/store

  • ng add @ngxs/logger-plugin

  • ng add @ngxs/devtools-plugin


Store:

Store is a global state manager, we are importing NgxModule from @ngxs/store.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './_ui/home/home.component';
import { NgxsModule } from '@ngxs/store';
import {TutorialState} from './_store/States/tutorial.state';
import { NgxsLoggerPluginModule } from '@ngxs/logger-plugin';
import { NgxsReduxDevtoolsPluginModule } from '@ngxs/devtools-plugin';
import {ReactiveFormsModule} from '@angular/forms';
 
@NgModule({
 declarations: [
   AppComponent,
   HomeComponent
 ],
 imports: [
   BrowserModule,
   AppRoutingModule,
   NgxsModule.forRoot([TutorialState]),
   NgxsLoggerPluginModule.forRoot(),
   NgxsReduxDevtoolsPluginModule.forRoot(),
   ReactiveFormsModule,
 
 
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }


Let’s create Actions :

We are now going to create actions that we dispatch, each action containing a type field and payload.

import { Tutorial } from "src/app/_models/tutorial.interface";
 
export class AddTutorial {
 static readonly type = '[Tutorial] Add';
 
 constructor(public payload: Tutorial){}
}
 
export class RemoveTutorial {
 static readonly type = '[Tutorial] Remove';
 
 constructor(public payload: string) {}
}

Now the most important thing in ngxs is to create state.


Let’s create state now:

State: state are classes along with decorator that describe the metadata and action.

We can define state as:

@State<TutorialStateModel>({
 name: 'tutorial',
 defaults: {
   tutorial: []
 }
})

name in state is used to select the state, or we can say that its specific state and default in the state describe the state’s default data.

import {State , Action , StateContext, Selector} from '@ngxs/store';
import * as TutorialAction from '../Actions/tutorial.action';
import { Tutorial } from '../../_models/tutorial.interface';
 
 
export class  TutorialStateModel {
 tutorial: Tutorial[];
}
 
@State<TutorialStateModel>({
 name: 'tutorial',
 defaults: {
   tutorial: []
 }
})
 
export class TutorialState {
 
 @Selector()
 static getTutorial(state: TutorialStateModel): Tutorial[]{
   return state.tutorial;
 }
 
 
 @Action(TutorialAction.AddTutorial)
 get({ getState, patchState}: StateContext<TutorialStateModel>, {payload}: TutorialAction.AddTutorial): any{
   const state = getState();
   patchState({ tutorial: [...state.tutorial , payload]
   });
 }
 
 @Action(TutorialAction.RemoveTutorial)
 remove({ getState, patchState}: StateContext<TutorialStateModel>, {payload}: TutorialAction.RemoveTutorial): any{
   patchState({ tutorial: getState().tutorial.filter(tutorial => tutorial.name !== payload)
   });
 }
}


Select:

Select is a function that allows us to select a specific state or specific part of the state. Specific parts of data from the store are selected by using the @Select decorator.

import { Component, OnInit } from '@angular/core';
import { Select, Store } from '@ngxs/store';
import { Observable } from 'rxjs';
import { Tutorial } from 'src/app/_models/tutorial.interface';
import { AddTutorial } from 'src/app/_store/Actions/tutorial.action';
import { TutorialState } from 'src/app/_store/Satates/tutorial.state';
 
@Component({
 selector: 'app-home',
 templateUrl: './home.component.html',
 styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {
// selecting state
@Select(TutorialState.getTutorial)tutorials$: Observable<Tutorial[]>;
 constructor(private store: Store) {
 }
 
 addTutorial(name: string, url: string): void{
   this.store.dispatch(new AddTutorial({  name,  url})); // dispatch an 
                                                          //action
 }
 
}


Conclusion:

In this post we learn about ngxs, In ngxs how we can create state and action, and how we can dispatch action and select a state. Now we can easily understand why NGXS is replacement of NGRX. Ngxs reduce boilerplate code and help us to manage the state of our application easily.



Source: Medium - Knoldus Inc.


The Tech Platform

0 comments

Comentarios


bottom of page