DEV Community

sunitha-premakumaran
sunitha-premakumaran

Posted on

State Management

I am sure you have heard about state management when it comes to developing enterprise applications. Let’s get started with the concept by understanding what it means for us and how it helps us build a Reactive application. This blog will focus on how to maintain state in Angular applications but the concepts are the same for all the component based frameworks including React and Vue Js.

What is State management?

State in application is the single source of truth containing the user contexts or other global information. Let us consider the scenario where you wanna build an application which will use login functionality. Let’s say you have multiple components using the login information to display the information about the login like Login name, email and your avatar, when you update any of these information you want all the components capture and reflect this change. With state management you can handle this change and make sure that the data is available from a single place for consumption that components can rely on and use in a reusable and structured way.

State management libraries for Javascript

There are a lot of libraries for State management for Javascript frameworks. Most of these libraries use the Redux pattern to manage the state. The most used frameworks use RxJs pattern in their implementation as RxJs strongly promotes Reactive programming for applications. NgRx is one such framework for State management for Angular applications.

Components of State management

Store

This component takes care of all the input and output operations concerned with the application state. The below snippet defines a way to handle State for a Todo application.

export interface TodoState {
    todos: string[];
    loading?: boolean;
}
Enter fullscreen mode Exit fullscreen mode

Action

Actions are how the change is transpiled. The below snippet is an example of using actions from ngrx/store that is defined to handle the particular case of adding a todo. This action has to dispached to store when an end user is trying to perform an action.

import { Action } from '@ngrx/store';

export class PostTodo implements Action {
    readonly type = 'POST_TODO';
    payload: string;

    constructor(payload: string) {
        this.payload = payload;
    }
}
Enter fullscreen mode Exit fullscreen mode

Effects

Effect is the way to handle javascript’s asynchronous code like invoking http requests and such. The following snippet is an example for a Side Effect for a Http post that will be triggered once the PostTodo action is dispached as a result of change in UI.

@Effect() todoPersist = this.actions$.pipe(
        ofType('POST_TODO'),
        switchMap((payload: string) => {
            return this.http.post(
                'https://demo9257915.mockable.io/todos',
                {
                    payload: payload
                }
            ).pipe(
                map((data: string) => {
                    return new AddTodo(data);
                }),
                catchError(error => {
                    return of(null);
                })
            )
        })
    );
Enter fullscreen mode Exit fullscreen mode

Reducer

This is a javascript function that makes a copy of state and makes changes and returns new state along with old state since changes made in the application have to be immutable.

export function todoReducer(state = initialState, action: TodoType) {

    switch (action.type) {
        case 'ADDED_TODO': {
            return {
                ...state,
                todos: [
                    ...state.todos,
                    action.payload
                ]
            }
        };
        case 'POST_TODO': {
            return {
                ...state,
                loading: true
            };
        };
    }
}
Enter fullscreen mode Exit fullscreen mode

Selector

Selector is used to subscribe specific changes to your state change and update the UI depending on the change. The following snippet subscribes to added todos and updates the UI accordingly after the server creates a todo.

 ngOnInit() {
    //Observable for the key todoList, subscribed value using async pipe in component template
    this.store.select('todoList').subscribe(data => {
      this.array = data.todos;
    });
  }
Enter fullscreen mode Exit fullscreen mode

Summary

While state management in your application gives you the leverage to handle reads and updates to your application data it also adds a lot of complexity if your Single page application is small in size. For cases with small applications it is better to handle your application state using RxJs alone. A complete working of managing state using NgRx in angular applications can be found here.

Discussion (0)