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 🙂
1 Comment