Angular State Management with NgRx
Tags: angular, webdev, javascript
Published: 2022-04-13 13:58:14

---
title: Angular State Management with NgRx
published: true
date: 2022-04-13 12:55:27 UTC
tags: angular, webdev, javascript
canonical_url: https://www.syncfusion.com/blogs/post/angular-state-management-with-ngrx.aspx
cover_image: https://www.syncfusion.com/blogs/wp-content/uploads/2022/04/Angular-State-Management-with-NgRx-672x372.png
---

State management is the process of managing the states of user controls. It helps developers build large-scale applications with heavy data communications while sustaining high application performance.

When it comes to Angular, NgRx and NGXS are the two most-used libraries for state management, and they have some unique features that make developers’ work easy.

In this article, I will introduce NgRx and walk you through the steps of creating a simple Angular application using it.

## What is NgRx?

![NgRx Website](https://www.syncfusion.com/blogs/wp-content/uploads/2022/04/NgRx-Website.png)
<figcaption>NgRx Website</figcaption>

NgRx is inspired by Redux and helps developers simplify the application’s state in objects by enforcing a unidirectional data flow.

## How NgRx works

![NgRx state management process](https://www.syncfusion.com/blogs/wp-content/uploads/2022/04/NgRx-state-management-process.jpg)The NgRx state management process is a combination of five key elements:

- **Store** : The application state is maintained in the store. It is immutable.
- **Selectors** : Angular components can subscribe to the store and get updates through selectors.
- **Reducers** : Reducers are responsible for handling the transition from one state to another.
- **Actions** : Actions modify the state of the store by using reducers.
- **Effects** : Effects are the results of actions. Also, they can be used to listen for particular action types and run when the action happens.

Although this process seems complex to implement, it is useful for data communication when the application grows.

So, let’s see how we can use NgRx in an Angular application.

## How to use NgRx store with Angular

In this tutorial, we will be implementing a simple application to manage blog articles using NgRx store and Angular.

### Step 1: Installing NgRx

[NgRx](https://ngrx.io/ "NgRx") can be installed using NPM, Yarn, or Angular CLI as follows:

```
// NPM
npm install @ngrx/store --save``// Yarn
yarn add @ngrx/store``// Angular CLI
ng add @ngrx/store@latest
```

### Step 2: Creating the Store

After installation, you need to create a separate directory named **/store** under the **src/app**  directory. This folder will contain all the files related to the NgRx store. The folder structure of the store directory would look like this:

```
-- app-- src-- app-- store
-- models-- actions
-- reducers
```

As a first step, you need to create an interface for articles. Let’s name the model **article.model.ts**.

```js
export interface Article {
  id: string;
  name: string;
  author: string;
  publisher: string;
}
```

Then, you need to create an action file to define NgRx actions. Here, we have created a file named **articles.actions.ts** under the **actions** folder and imported **Actions** from the NgRx store.

```js
import { Action } from '@ngrx/store';
import { Article } from '../models/article.model';

export enum ArticleActionType {
  ADD_ITEM = '[ARTICLE] Add ARTICLE',
}

export class AddArticleAction implements Action {

  readonly type = ArticleActionType.ADD_ITEM;
  constructor(public payload: Article) {}

}

export type ArticleAction = AddArticleAction;
```

In the above action file, we defined an action as a constant using **enum.** Then, we implemented the **AddArticleAction** class from the NgRx **Action** class, which accepts two parameters: a type and an optional payload.

Now, we need to create a reducer to help us in state transitions. So, inside the reducers directory, create a  **course.reducer.ts**  file with the following content:

```js
import { Article } from '../models/article.model';
import { ArticleAction, ArticleActionType } from '../actions/article.actions';

const initialState: Array<Article> = [
  {
    id: '1',
    name: 'Angular State Management with NgRx',
    author: 'Chameera Dulanga',
    publisher: 'SyncFusion'
  },
];

export function ArticleReducer(
   state: Array<Article> = initialState,
   action: ArticleAction
) {
   switch (action.type) {
     case ArticleActionType.ADD_ITEM:
       return [...state, action.payload];
     default:
       return state;
   }
}
```

In the above reducer, we have created an initial state for the **Article** interface and a reducer function named **ArticleReducer** Which accepts a state and an action as input parameters. If the action type is **ADD\_ITEM** , it will return the state and the payload. Otherwise, it will only return the state.

For the final step of store creation, we need to create another model to keep all application states in a single place. Here, we have named it **state.model.ts** and it will look like this:

```js
import { Article } from '../models/article.model';

export interface State {
  readonly article: Array<Article>;
}
```

### Step 3: Registering the NgRx store

Now, you need to register the NgRx store in the Angular application. To do this, import the reducer created in the previous step to the **app.module.ts** file and include it in the **imports** array.

```js
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';

import { StoreModule } from '@ngrx/store';
import { ArticleReducer } from './store/reducers/article.reducer';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule, 
    StoreModule.forRoot({
      course: CourseReducer,
    }),
  ],
  providers: [],
  bootstrap: [AppComponent]
})

export class AppModule { }
```

### Step 4: Using the NgRx store

After registering the store in **AppModule,** you can start using it in your components. Here, we will be using **AppComponent** to display and add articles to the store.

```js
import { Component, OnInit } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs';
import { CourseItem } from './store/models/courseItem.model';
import { AppState } from './store/models/app-state.model';
import { NgForm } from '@angular/forms';
import { AddItemAction } from './store/actions/course.action';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
})

export class AppComponent implements OnInit {
  articles$: Observable<Array<Article>>;
  constructor(private store: Store<State>) {}

  ngOnInit(): void {
    this.articles$ = this.store.select((store) => store.article);
  }

  addArticle(form: NgForm) {
    this.store.dispatch(
      new AddArticleAction(form.value)
    );
    form.reset();
  }

}
```

The above code shows the **app.component.ts** file of our example. There, we have set **articles$** to a type of observable and subscribed to the store to get the articles. The **addArticle()** function is responsible for dispatching new articles to the store.

Now, we need to modify the **app.component.html** file to display and create articles.

```html
<section>
 <div class="container">
  <div class="row" style="margin-top: 5%;">
   <div class="col-md-12" style="text-align: center; margin: 5%;">
    <h2>My Articles</h2>
   </div>
   <div class="col-md-6">
    <div class="card p-4 shadow-sm">
     <form #myform="ngForm" (ngSubmit)="addArticle(myform)">
      <div class="form-group">
       <label for="name">Article Id</label>
       <input
         type="text"
         class="form-control"
         ngModel
         name="id"
         id="id"
         aria-describedby="identity"
         required
       />
      </div>
      <div class="form-group">
       <label for="title">Title</label>
       <input
         type="text"
         class="form-control"
         ngModel
         name="title"
         id="title"
         aria-describedby="title"
       />
      </div>
      <div class="form-group">
       <label for="author">Author</label>
       <input
         type="text"
         class="form-control"
         ngModel
         name="author"
         id="author"
       />
      </div>
      <div class="form-group">
       <label for="publisher">Publisher</label>
       <input
         type="text"
         class="form-control"
         ngModel
         name="publisher"
         id="publisher"
       />
      </div>
      <button type="submit" class="btn btn-primary">Submit</button>
     </form>
    </div>
   </div>
   <div class="col-md-6">
    <ul class="list-group">
     <li class="list-group-item list-group-item-primary" *ngFor="let article of articles$ | async">
      {{article.title}} <b>{{article.author}}</b>
     </li>
    </ul>
   </div>
  </div>
 </div>
</section>
```

![Screenshot of the application demonstrating NgRX](https://www.syncfusion.com/blogs/wp-content/uploads/2022/04/Screenshot-of-the-application-demonstrating-NgRX.png)That’s all there is to it! We have successfully configured an NgRx store with an Angular application. You can find the complete code of this example in this [GitHub repository](https://github.com/SyncfusionExamples/angular-state-management-with-ngrx "Angular State Management with NgRx demo on GitHub").

## Conclusion

NgRx is one of the most-used libraries for state management in Angular applications. I hope this article gives you a head start in creating your own Angular application using NgRx.

Thank you for reading!

Syncfusion’s [Angular UI component](https://www.syncfusion.com/angular-ui-components "Angular UI components") library is the only suite you will ever need to build an application, containing over 65 high-performance, lightweight, modular, and responsive UI components in a single package.

For existing customers, the newest Essential Studio version is available for download from the [License and Downloads](https://www.syncfusion.com/account/downloads "License and download page of Essential Studio") page. If you are not yet a Syncfusion customer, you can try our 30-day [free trial](https://www.syncfusion.com/downloads "Free evaluation of the Syncfusion Essential Studio") to check out the available features. Also, check out our demos on [GitHub](https://github.com/syncfusion "Syncfusion examples on GitHub").

You can contact us through our [support forums](https://www.syncfusion.com/forums "Syncfusion support forum"), [support portal](https://support.syncfusion.com/ "Syncfusion support portal"), or [feedback portal](https://www.syncfusion.com/feedback/angular "Syncfusion Feedback Portal"). We are always happy to assist you!

## Related blogs

- [Efficiently Bind Data to the Angular Data Grid and Perform CRUD Operations Using GraphQL](https://www.syncfusion.com/blogs/post/efficiently-bind-data-to-the-angular-data-grid-and-perform-crud-operations-using-graphql.aspx "Efficiently Bind Data to the Angular Data Grid and Perform CRUD Operations Using GraphQL blog")
- [How to Build a CRUD App in Angular](https://www.syncfusion.com/blogs/post/how-to-build-a-crud-app-in-angular.aspx "How to Build a CRUD App in Angular blog")
- [Easy Steps to Host an Angular App in GitHub Pages](https://www.syncfusion.com/blogs/post/easy-steps-to-host-an-angular-app-in-github-pages.aspx "Easy Steps to Host an Angular App in GitHub Pages blog")
- [Entering Invalid Dates Just Got Better in Angular Apps](https://www.syncfusion.com/blogs/post/entering-invalid-dates-is-not-possible-anymore-in-angular-apps.aspx "Entering Invalid Dates Just Got Better in Angular Apps blog")