Skip to content
Angular Essentials
GitHub

NgRx store actions

NgRx Store provides state management for creating maintainable, explicit applications through the use of single state and actions in order to express state changes.

  • Why use NgRx Store? Give read here

Actions

  • Actions express unique events that happen throughout your application.
  • Events like api requests, user interaction with page and son are described using actions.
  • Actions help to understand how events are handled in your application.

Action interface

  • An Action in NgRx is made up of a simple interface:
interface Action {
  type: string;
}
  • The type property is for describing the action that will be dispatched in an application.
  • The value of the type comes in the form of [Source] Event and is used to provide a context of what category of action it is, and where an action was dispatched from. For example, to delete todo the type will be [Todo Component] Delete Todo where [Todo Component] is Source and Delete Todo is Event.

Creating action for todo component

  • Before we jump into code, let’s list down what could be action in our todo component
    • Adding new todo
    • Modifying/updating existing todo (done status: true/false)
    • Deleting todo
  • Create a new action file viz todo.actions.ts inside store folder of todo to describe todo actions to add, modify and delete
  • createAction() creates a configured Creator function, Creator function when called returns an object in the shape of the Action interface
  • createActin() take two params
    • type which describes the action that will be dispatched
    • config which defines additional metadata needed for the handling of the action. By default, it is undefined
  • props method is used to define any additional metadata needed for the handling of the action.
    • For example, to deleteTodo we need additional info which is todoId.
  • Action creators provide a consistent, type-safe way to construct an action that is being dispatched.
  • More here
// todo.actions.ts
import {createAction} from '@ngrx/store';

export const saveOrUpdateTodo = createAction(
  '[Todo Component] Update Todo',
  props<{todo: Todo, isUpdate: boolean}>()
);

export const deleteTodo = createAction(
  '[Todo Component] Delete Todo',
  props<{todoId: number}>()
);

Dispatching created action

export class TodoComponent implements OnInit {

  undoOrCompleteTodo(item: Todo) {
    this.todos = this.todos.map(todo => todo.id === item.id ? {...todo, done: !todo.done} : todo);
    const todo: Todo = {...item, done: !item.done};
    this.store.dispatch(saveOrUpdateTodo({todo, isUpdate: true}));
  }

  deleteTodo(todoId: number) {
    const todo = this.todos.find(todo => todo.id === todoId);
    if (todo) {
      this.todos.splice(this.todos.indexOf(todo), 1);
    }
    this.store.dispatch(deleteTodo({todoId}))
  }

  addTodo(): void {
    if (this.todoIdFormControl.value && this.todoIdFormControl.value >= 0 && !this.todos.find(t => t.id === this.todoIdFormControl.value)) {
      const todo: Todo = {
        id: this.todoIdFormControl.value,
        description: this.todoDescriptionFormControl.value ?? '',
        done: false
      }
      this.todos.push(todo);
      this.store.dispatch(saveOrUpdateTodo({todo, isUpdate: false}));
    }
  }
}

Let’s break down what’s happening. For example, this.store.dispatch(saveOrUpdateTodo({todo, isUpdate: true}))

The saveOrUpdateTodo action creator receives an object of todo and isUpdate and returns a plain JavaScript object with a type property of [Todo Component] Update Todo, with todo and isUpdate as additional properties.

The JavaScript object will be of following format.

{
  type: '[Todo Component] Update Todo',
  todo : {id: 123, description : 'First todo', done : true},
  isUpdate: true
}

The returned action has a very specific context about where the action came from and what event happened.

  • The category of the action is captured within the square brackets [].
  • The category is used to group actions for a particular area, whether it be a component page, backend API, or browser API.
  • The Update Todo text after the category is a description about what event occurred from this action. In this case, the user updated the status from completed to undo or vice versa.

You can also write actions using class-based action creators, which was the previously defined way before action creators were introduced in NgRx.