Complete todo list CRUD project in angular 18 with example

 Creating a simple CRUD (Create, Read, Update, Delete) Todo List application in Angular 18 involves setting up Angular components, services, and using forms for input. We'll assume the Angular CLI is already installed and set up.

Step-by-Step Guide:

  1. Set Up Angular Project
  2. Create Todo Service
  3. Create Components: Todo List, Todo Form, Todo Item
  4. Wire Everything Together
  5. Add Routing for Navigation (Optional)

1. Set Up Angular Project

Create a new Angular project using the Angular CLI:

bash
ng new todo-app cd todo-app ng serve

This will start a development server at http://localhost:4200.

2. Install Angular Forms Module

To use Angular forms (template-driven or reactive forms), you need to import FormsModule and ReactiveFormsModule into your app.

Open app.module.ts and import these modules:

typescript
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AppComponent } from './app.component'; import { TodoListComponent } from './todo-list/todo-list.component'; import { TodoFormComponent } from './todo-form/todo-form.component'; @NgModule({ declarations: [ AppComponent, TodoListComponent, TodoFormComponent ], imports: [ BrowserModule, FormsModule, ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }

3. Create Todo Service

The TodoService will handle CRUD operations like creating, retrieving, updating, and deleting tasks.

Create todo.service.ts inside the src/app/ folder:

typescript
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; export interface Todo { id: number; title: string; completed: boolean; } @Injectable({ providedIn: 'root' }) export class TodoService { private todos: Todo[] = []; private todosSubject = new BehaviorSubject<Todo[]>(this.todos); getTodos() { return this.todosSubject.asObservable(); } addTodo(todo: Todo) { todo.id = this.todos.length + 1; // Simple ID generator this.todos.push(todo); this.todosSubject.next(this.todos); } updateTodo(updatedTodo: Todo) { const index = this.todos.findIndex(todo => todo.id === updatedTodo.id); if (index !== -1) { this.todos[index] = updatedTodo; this.todosSubject.next(this.todos); } } deleteTodo(id: number) { this.todos = this.todos.filter(todo => todo.id !== id); this.todosSubject.next(this.todos); } }

This service uses BehaviorSubject to hold and update the list of todos.

4. Create Todo Components

Todo List Component (todo-list.component.ts)

The TodoListComponent displays the list of tasks.

typescript
import { Component, OnInit } from '@angular/core'; import { TodoService, Todo } from '../todo.service'; @Component({ selector: 'app-todo-list', templateUrl: './todo-list.component.html', styleUrls: ['./todo-list.component.css'] }) export class TodoListComponent implements OnInit { todos: Todo[] = []; constructor(private todoService: TodoService) { } ngOnInit(): void { this.todoService.getTodos().subscribe(todos => { this.todos = todos; }); } deleteTodo(id: number) { this.todoService.deleteTodo(id); } toggleComplete(todo: Todo) { todo.completed = !todo.completed; this.todoService.updateTodo(todo); } }

todo-list.component.html

html
<div *ngIf="todos.length > 0; else noTodos"> <ul> <li *ngFor="let todo of todos"> <span [class.completed]="todo.completed">{{ todo.title }}</span> <button (click)="toggleComplete(todo)">Toggle</button> <button (click)="deleteTodo(todo.id)">Delete</button> </li> </ul> </div> <ng-template #noTodos> <p>No Todos available.</p> </ng-template>

Add some styles for the completed tasks (optional):

css
.completed { text-decoration: line-through; }

Todo Form Component (todo-form.component.ts)

This component is used to add a new Todo.

typescript
import { Component, Output, EventEmitter } from '@angular/core'; import { TodoService, Todo } from '../todo.service'; import { FormBuilder, FormGroup, Validators } from '@angular/forms'; @Component({ selector: 'app-todo-form', templateUrl: './todo-form.component.html', styleUrls: ['./todo-form.component.css'] }) export class TodoFormComponent { todoForm: FormGroup; constructor( private todoService: TodoService, private fb: FormBuilder ) { this.todoForm = this.fb.group({ title: ['', Validators.required] }); } onSubmit() { if (this.todoForm.valid) { const newTodo: Todo = { id: 0, title: this.todoForm.value.title, completed: false }; this.todoService.addTodo(newTodo); this.todoForm.reset(); } } }

todo-form.component.html

html
<form [formGroup]="todoForm" (ngSubmit)="onSubmit()"> <input formControlName="title" placeholder="Enter Todo" /> <button type="submit" [disabled]="todoForm.invalid">Add Todo</button> </form>

5. Wire Everything Together

Now, in the main app.component.html, use the TodoListComponent and TodoFormComponent:

html
<h1>Todo App</h1> <app-todo-form></app-todo-form> <app-todo-list></app-todo-list>

6. Optionally Add Routing (for better organization)

You can add routing in your application to navigate between different pages like "All Todos", "Completed Todos", etc.

Add Routes in app-routing.module.ts:

typescript
import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; import { TodoListComponent } from './todo-list/todo-list.component'; const routes: Routes = [ { path: '', component: TodoListComponent }, ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }

Import AppRoutingModule in app.module.ts:

typescript
import { AppRoutingModule } from './app-routing.module';

And update your app.component.html to add a router outlet:

html
<router-outlet></router-outlet>

7. Running the Application

To start your application, use the following command:

bash
ng serve

Navigate to http://localhost:4200 to view your CRUD Todo list application.


Conclusion:

This is a basic Todo List CRUD app using Angular 18 with services, components, and form handling. You can enhance it by adding features like editing todos, saving data in local storage, or adding animations for task updates.

Comments

Popular posts from this blog

PrimeNG tutorial with examples using frequently used classes

Docker and Kubernetes Tutorials and QnA

oAuth in angular