todo application using angular

Angular Series Part 5 - Create a TODO App

December 31, 2022

VinoPravin

Angular Series Part 5 - Create a TODO App

Post last updated: December 31, 2022

How to create a TODO Application with Angular Step by Step

With all the theoretical Knowledge we have learned, we are goind to create a wonderful todo app. Please follow the steps along

image alt text

1. Create a new Angular project by running the following command in your terminal:

terminal
ng new todo-app

2. Install Angular Material and the Angular CDK by running the following command in your terminal:

terminal
npm install --save @angular/material @angular/cdk

3. Import the MatButtonModule, MatCardModule, MatDialogModule, and MatFormFieldModule from the @angular/material module in your application's root module (e.g. app.module.ts):

app.module.ts
import {
  MatButtonModule,
  MatCardModule,
  MatDialogModule,
  MatFormFieldModule
} from '@angular/material'

4. Add the imported modules to the imports array of your application's root module:

app.module.ts
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    MatButtonModule,
    MatCardModule,
    MatDialogModule,
    MatFormFieldModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

5. Create a service to manage the todos by running the following command in your terminal:

terminal
ng generate service todo

6. In the todo.service.ts file, define an array of todo objects and add methods to add, remove, and update todos:

todo.service.ts
import { Injectable } from '@angular/core'

@Injectable({
  providedIn: 'root'
})
export class TodoService {
  todos: any[] = [
    { id: 1, title: 'Todo 1', description: 'Description 1' },
    { id: 2, title: 'Todo 2', description: 'Description 2' },
    { id: 3, title: 'Todo 3', description: 'Description 3' }
  ]

  constructor() {}

  getTodos() {
    return this.todos
  }

  addTodo(todo) {
    this.todos.push(todo)
  }

  removeTodo(todo) {
    const index = this.todos.indexOf(todo)
    this.todos.splice(index, 1)
  }

  updateTodo(todo) {
    const index = this.todos.indexOf(todo)
    this.todos[index] = todo
  }
}

7. Create a component for the todo list by running the following command in your terminal:

terminal
ng generate component todo-list

8. In the todo-list.component.ts file, inject the TodoService and use the service's methods to get, add, remove, and update todos:

todo-list.component.ts
import { Component, OnInit } from '@angular/core';
import { TodoService } from '../todo.service';

@Component({
  selector: 'app-todo-list',
  templateUrl: './todo-list.component.html',
  styleUrls: ['./todo-list.component.css']
})
export class TodoListComponent implements OnInit {

  todos: any[];

  constructor(private todoService: TodoService) { }

  ngOnInit() {
    this.todos = this.todoService.getTodos();
  }

  addTodo(todo) {
    this.todoService.addTodo(todo);
  }

  removeTodo(todo) {
    this.todoService.removeTodo(todo);
  }

  updateTodo(todo) {
    this.todoService.updateTodo(todo);
  }

}

9. In the todo-list.component.html file, use the *ngFor directive to iterate over the todos and display them in a list, and use the component's methods to add, remove, and update todos:

todo-list.component.html
<ul>
  <li *ngFor="let todo of todos">
    {{ todo.title }}
    <button (click)="removeTodo(todo)">Remove</button>
  </li>
</ul>

<button (click)="openAddDialog()">Add todo</button>

<mat-dialog-container>
  <mat-dialog #addDialog>
    <form #addForm="ngForm" (ngSubmit)="addTodo(addForm.value)">
      <mat-form-field>
        <input
          matInput
          type="text"
          name="title"
          ngModel
          required
          placeholder="Title"
        />
      </mat-form-field>
      <mat-form-field>
        <input
          matInput
          type="text"
          name="description"
          ngModel
          required
          placeholder="Description"
        />
      </mat-form-field>
      <button mat-button type="submit">Add</button>
    </form>
  </mat-dialog>
</mat-dialog-container>

<mat-dialog-container>
  <mat-dialog #updateDialog>
    <form #updateForm="ngForm" (ngSubmit)="updateTodo(updateForm.value)">
      <mat-form-field>
        <input
          matInput
          type="text"
          name="title"
          [(ngModel)]="selectedTodo.title"
          required
          placeholder="Title"
        />
      </mat-form-field>
      <mat-form-field>
        <input
          matInput
          type="text"
          name="description"
          [(ngModel)]="selectedTodo.description"
          required
          placeholder="Description"
        />
      </mat-form-field>
      <button mat-button type="submit">Update</button>
    </form>
  </mat-dialog>
</mat-dialog-container>

10. In the todo-list.component.ts file, add methods to open the add and update dialogs and select a todo for updating:

todo-list.component.ts
import { Component, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material';
import { TodoService } from '../todo.service';

@Component({
  selector: 'app-todo-list',
  templateUrl: './todo-list.component.html',
  styleUrls: ['./todo-list.component.css']
})
export class TodoListComponent implements OnInit {

  todos: any[];
  selectedTodo: any;

  constructor(private todoService: TodoService, private dialog: MatDialog) { }

  ngOnInit() {
    this.todos = this.todoService.getTodos();
  }

  openAddDialog() {
    this.dialog.open(this.addDialog);
  }

  openUpdateDialog(todo) {
    this.selectedTodo = todo;
    this.dialog.open(this.updateDialog);
  }

  addTodo(todo) {
    this.todoService.addTodo(todo);
    this.dialog.closeAll();
  }

  removeTodo(todo) {
    this.todoService.removeTodo(todo);
  }

  updateTodo(todo) {
    this.todoService.updateTodo(todo);
    this.dialog.closeAll();
  }
}

11. Create a component for the todo detail page by running the following command in your terminal:

terminal
ng generate component todo-detail

12. In the todo-detail.component.ts file, inject the TodoService and use the service's methods to get and update a todo:

todo-detail.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { TodoService } from '../todo.service';

@Component({
  selector: 'app-todo-detail',
  templateUrl: './todo-detail.component.html',
  styleUrls: ['./todo-detail.component.css']
})
export class TodoDetailComponent implements OnInit {

  todo: any;

  constructor(private route: ActivatedRoute, private todoService: TodoService)

  ngOnInit() {
    const id = +this.route.snapshot.paramMap.get('id');
    this.todo = this.todoService.getTodos().find(todo => todo.id === id);
  }

  updateTodo(todo) {
    this.todoService.updateTodo(todo);
  }
}

13. In the todo-detail.component.html file, use the [(ngModel)] directive to bind the todo object to a form for updating:

todo-detail.component.html
<form #updateForm="ngForm" (ngSubmit)="updateTodo(updateForm.value)">
  <mat-form-field>
    <input
      matInput
      type="text"
      name="title"
      [(ngModel)]="todo.title"
      required
      placeholder="Title"
    />
  </mat-form-field>
  <mat-form-field>
    <input
      matInput
      type="text"
      name="description"
      [(ngModel)]="todo.description"
      required
      placeholder="Description"
    />
  </mat-form-field>
  <button mat-button type="submit">Update</button>
</form>

14. In the app.module.ts file, import the RouterModule and Routes from the @angular/router module, and define routes for the todo list and todo detail pages:

app.module.ts
import { RouterModule, Routes } from '@angular/router'

const routes: Routes = [
  { path: '', redirectTo: '/todos', pathMatch: 'full' },
  { path: 'todos', component: TodoListComponent },
  { path: 'todo/:id', component: TodoDetailComponent }
]

@NgModule({
  declarations: [AppComponent, TodoListComponent, TodoDetailComponent],
  imports: [
    BrowserModule,
    MatButtonModule,
    MatCardModule,
    MatDialogModule,
    MatFormFieldModule,
    RouterModule.forRoot(routes)
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

15. In the app.component.html file, use the router-outlet directive to display the active route:

app.component.html
<router-outlet></router-outlet>
Hurray! You Just Created Your First Angular Application! :)

You can watch a complete video tutorial here! :)

Author

VinoPravin

A Professional Full Stack Web Developer based in India. I help some of the fastest growing startups launch and grow their products.