Blog>
Snippets

Immutable Data Patterns with NgRx Store

Explores using Angular's NgRx Store for state management with immutable data patterns, ensuring a consistent unidirectional data flow in a larger application.
// actions.ts
import { createAction, props } from '@ngrx/store';

export const addTodo = createAction(
  '[Todo List] Add Todo',
  props<{ todo: string }>()
);
Defines an NgRx action to add a new todo item. The action is created using the createAction function with a specific type '[Todo List] Add Todo' and a payload containing the new todo as a string.
// reducer.ts
import { createReducer, on } from '@ngrx/store';
import * as TodoActions from './actions';

export const initialState = [];

export const todoReducer = createReducer(
  initialState,
  on(TodoActions.addTodo, (state, { todo }) => [...state, todo])
);
Sets up the todoReducer using createReducer that takes an initial state of empty array. The on function listens for the addTodo action and returns a new state with the new todo added, ensuring immutability by spreading the previous state and appending the new todo item.
// selectors.ts
import { createSelector } from '@ngrx/store';

export const selectTodos = state => state.todos;

export const selectTodoList = createSelector(
  selectTodos,
  (todos) => todos
);
Creates a selector for the todos using createSelector. The selectTodos is a simple arrow function that returns the todos state. Then selectTodoList uses the createSelector function to get the todos state and returns it as is.
// component.ts
import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import * as TodoActions from './actions';
import * as fromTodoSelectors from './selectors';

@Component({
  selector: 'app-todo-list',
  template: `<!-- Todo List Template -->`
})
export class TodoListComponent {
  todos$ = this.store.select(fromTodoSelectors.selectTodoList);

  constructor(private store: Store) {}

  addTodo(todo: string) {
    this.store.dispatch(TodoActions.addTodo({ todo }));
  }
}
This is an Angular component that interacts with the NgRx store. It uses the select method from the store service to subscribe to the todo list from the state, creating an observable todos$. The addTodo method dispatches the addTodo action from the actions file to add a new todo to the state.