Master Angular NgRx by creating a To-Do Application

In this article we are building a todo application using Angular NgRx, NgRx is used for state management in angular applications.

Let’s start by creating a new Angular project if you haven’t already

ng new ngrx-todo-app

Go inside the project directory

cd ngrx-todo-app

Install the required angular NgRx packages

ng add @ngrx/store
ng add @ngrx/effects

Define the structure of your application’s state and actions for Angular NgRx project

Create a folder named actions in the src/app directory. In this folder, create an actions.ts file

import { createAction, props } from '@ngrx/store';

export const addTodo = createAction('[Todo] Add Todo', props<{ text: string }>());
export const completeTodo = createAction('[Todo] Complete Todo', props<{ id: number }>());

Create a folder named reducers in the src/app directory. In this folder, create a todos.reducer.ts file

import { createReducer, on } from '@ngrx/store';
import { addTodo, completeTodo } from '../actions/actions';

export interface Todo {
  id: number;
  text: string;
  completed: boolean;
}

export interface TodoState {
  todos: Todo[];
}

export const initialState: TodoState = {
  todos: [],
};

export const todoReducer = createReducer(
  initialState,
  on(addTodo, (state, { text }) => ({ ...state, todos: [...state.todos, { id: state.todos.length + 1, text, completed: false }] })),
  on(completeTodo, (state, { id }) => ({ ...state, todos: state.todos.map(todo => (todo.id === id ? { ...todo, completed: true } : todo)) }))
);

Now, create a folder named effects in the src/app directory. In this folder, create a todos.effects.ts file

import { Injectable } from '@angular/core';
import { Actions, createEffect, ofType } from '@ngrx/effects';
import { addTodo, completeTodo } from '../actions/actions';
import { tap } from 'rxjs/operators';

@Injectable()
export class TodosEffects {
  constructor(private actions$: Actions) {}

  completeTodo$ = createEffect(
    () =>
      this.actions$.pipe(
        ofType(completeTodo),
        tap(action => {
          console.log(`Todo with ID ${action.id} completed.`);
        })
      ),
    { dispatch: false }
  );
}

In the src/app directory, create an index.ts file to export everything from the actions, reducers, and effects

export * from './actions/actions';
export * from './reducers/todos.reducer';
export * from './effects/todos.effects';

Now, its time to create a todo component for our Angular Ngrx Project.

ng generate component todo

In the src/app/todo directory, modify the todo.component.ts

import { Component } from '@angular/core';
import { Store } from '@ngrx/store';
import { addTodo } from '../actions/actions';

@Component({
  selector: 'app-todo',
  templateUrl: './todo.component.html',
  styleUrls: ['./todo.component.css'],
})
export class TodoComponent {
  newTodoText: string = '';

  constructor(private store: Store) {}

  addTodo() {
    if (this.newTodoText.trim() !== '') {
      this.store.dispatch(addTodo({ text: this.newTodoText }));
      this.newTodoText = '';
    }
  }
}

Modify the todo.component.html

<div>
  <input [(ngModel)]="newTodoText" placeholder="Add a new todo" />
  <button (click)="addTodo()">Add</button>
</div>

In the src/app/app.component.html, use the <app-todo></app-todo> tag to include the todo component

In the src/app/app.module.ts, configure the NgRx store and effects

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { StoreModule } from '@ngrx/store';
import { EffectsModule } from '@ngrx/effects';
import { FormsModule } from '@angular/forms';
import { AppComponent } from './app.component';
import { TodoComponent } from './todo/todo.component';
import { todoReducer } from './reducers/todos.reducer';
import { TodosEffects } from './effects/todos.effects';

@NgModule({
  declarations: [AppComponent, TodoComponent],
  imports: [
    BrowserModule,
    FormsModule,
    StoreModule.forRoot({ todos: todoReducer }),
    EffectsModule.forRoot([TodosEffects]),
  ],
  providers: [],
  bootstrap: [AppComponent],
})
export class AppModule {}

Run the app using the following command

ng serve

Our app should be accessible at http://localhost:4200.

This is a basic example of how you can create a todo app using Angular NgRx for state management.

If you have any doubts, please comment. Happy Coding 🙂

Related Posts

angular change detection techniques

Understanding Angular Change Detection for Beginners | Angular 17 Change Detection Methods

Understanding how the Angular change detection technique helps in the process of building dynamic and responsive web applications. In this article, we’ll explore some essential concepts of…

TypeScript Strategies for Angular, Explaining Best Practices and Techniques

Angular has fully embraced TypeScript as its primary development language, a decision that has evolved into a widely accepted standard practice. TypeScript introduces robust features for static…

Unlocking the Future of Web Development: A Deep Dive into Angular 17 Features

Angular 17, the powerhouse in the realm of JavaScript frameworks, celebrated its 13th anniversary recently. From its inception with AngularJS, the framework has continuously evolved to meet…

angular-icon

How to use ngx-spinner in Angular to create a loading spinner for smoother user interactions

In this article, we will create a loading spinner component with ngx-spinner in angular application. ngx-spinner in angular provides a loading spinner component that we can use…

angular-icon

Master AngularFire2 and Angular by building a CRUD operation app

In this article, we are creating a CRUD application with angularFire2 and angular, This module basically provides direct access to the Firebase database, and by using angular…

chart-js-angular

How to use Chart.js version 2 & 3 in angular application | Create line, bar, pie, and other important types of charts using chart js angular application

Chart.js library is open-source to create interactive and beautiful charts for your angular application. These charts are not just static charts, these are data-driven charts. Using the…

This Post Has One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *