Angular 8 Crud Todo Application Tutorial

Angular 8 Crud Todo Application Tutorial

In this tutorial angular 8 crud tutorial, we will learn how to implement crud todo application in Angular 8.

Befor get started with angular 8 crud operation. You must have installed Angular project.

So let’s get start:

Create Angular 8 Component

What is component?
Components are a logical piece of code for Angular JS application. We will create three component.

Type the following command to generate Angular 8 Components. We will perform create, read, update operations. So we will create three components.

To create it:

 ng g component todo
ng g component todoAdd
ng g component todoEdit

Open src/app/app.module.ts you will see all the three components imported and declared in declarations section by Angular 8 itself.

Create Angular 8 Routing

Now We need to create route for the above created component. So when you navigate the route you will be see the html of your component.

To create new route open the “app-routing.module.ts” file under the “your project directory > src > app”.

Import all three above created component to the routing module. Add the below line in the top of the “app-routing.module.ts” file.

 import { TodoComponent } from './todo/todo.component';
import { TodoAddComponent } from './todo-add/todo-add.component';
import { TodoEditComponent } from './todo-edit/todo-edit.component';

You will see the route variable. Changed with this

const routes: Routes = [
  {
    path: '',
    component: TodoComponent,
    data: { title: 'List of todos' }
  },
  {
    path: 'todo/add',
    component: TodoAddComponent,
    data: { title: 'Add todo' }
  },
  {
    path: 'todo/edit/:id',
    component: TodoEditComponent,
    data: { title: 'Edit todo' }
  },
];

Install bootstrap 4 CSS Framwork

Next, install the Bootstrap 4 CSS Framework using the following command.

npm install bootstrap --save

Now, add it inside the angular.json file.

"styles": [
"src/styles.css",
"./node_modules/bootstrap/dist/css/bootstrap.min.css"
]

So, now we can use the Bootstrap 4 classes in our project.

Configure the Angular 8 Form Validation

We will use ReactiveFormsModule for Angular 8 Form Validation.
Now, import the ReactiveFormsModule inside the app.module.ts file.

import { ReactiveFormsModule } from '@angular/forms'; 
imports: [

    ReactiveFormsModule

],

Modify Angular 8 entry page

Open src/app/app.component.html and modify this HTML page to fit the CRUD page. Replace with the following html

<router-outlet></router-outlet>

Modify todo list component

Open src/app/todo.component.html and put the below html

<div class="container mt-5">
  <h2>Todos
    <a class="float-right" [routerLink]="['/todo/add']">
      <button type="button" class="btn btn-primary">Add</button>
    </a>
  </h2>
  <table class="table table-bordered mt-5">
    <thead>
      <tr>
        <th>ID</th>
        <th>Title</th>
        <th>Action</th>
      </tr>
    </thead>
    <tbody>
        <tr *ngFor="let item of data; let i = index;">
            <td width="20">{{item.id}}</td>
            <td>{{item.title}}</td>
            <td width="250">                
                <button type="button" class="btn btn-danger mr-1" (click)="deleteTodo(item.id, i)">Delete</button>
                <a [routerLink]="['/todo/edit/', item.id]">
                  <button type="button" class="btn btn-primary">Edit</button>
                </a>
            </td>
          </tr>
    </tbody>
  </table>
</div>

Open src/app/todo.component.ts and put the below code

import { Component, OnInit } from '@angular/core';
import { ApiService } from '../api.service';
import { Todo } from '../todo';

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

  data: Todo[] = [];

  constructor(private api: ApiService) { }
  

  ngOnInit() {
    this.api.getTodos()
      .subscribe(res => {
        this.data = res;
      }, err => {
        console.log(err);
      });
  }

  deleteTodo(id, index) {
    this.api.deleteTodo(id)
      .subscribe(res => {    
          this.data.splice(index,1);
        }, (err) => {
          console.log(err);
        }
      );
  }
}

Modify todo add component

Open src/app/todo-add.component.html and put the below html

<div class="row mt-5">
  <div class="col-md-6 mx-auto">
      <h2 class="text-center">Add Todo</h2>
      <div class="card mt-3">
          <div class="card-body">
            <form [formGroup]="todoForm" (ngSubmit)="addTodo()">
              <div class="form-group">
                <label class="col-md-4">Title </label>
                <input type="text" class="form-control" formControlName="title" />
              </div>
              <div class="form-group">
                <button type="submit" class="btn btn-primary col-md-4" [disabled]="todoForm.invalid">Add</button>
                <a [routerLink]="['/']">
                  <button type="submit" class="btn btn-primary col-md-4 ml-1">Back</button>
                </a>
              </div>
            </form>
          </div>
      </div>
  </div>
</div>

Open src/app/todo-add.component.ts and put the below code

import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormGroup, Validators} from "@angular/forms";
import { ApiService } from '../api.service';
import {Router} from "@angular/router";

@Component({
  selector: 'app-todo-add',
  templateUrl: './todo-add.component.html',
  styleUrls: ['./todo-add.component.css']
})

export class TodoAddComponent implements OnInit {
  
  todoForm: FormGroup;
  constructor(private formBuilder: FormBuilder, private router: Router, private api: ApiService) { }


  ngOnInit() {
    this.todoForm = this.formBuilder.group({
      title: ['', Validators.compose([Validators.required])],
    });
  }

  addTodo() {
    const payload = {
      title: this.todoForm.controls.title.value,
    };

    this.api.addTodo(payload)
      .subscribe(res => {
          let id = res['_id'];
          this.router.navigate(['/']);
        }, (err) => {
          console.log(err);
        });
  }
}

Modify todo edit component

Open src/app/todo-edit.component.html and put the below html

<div class="row mt-5">
  <div class="col-md-6 mx-auto">
      <h2 class="text-center">Update Todo</h2>
      <div class="card mt-3">
          <div class="card-body">
            <form [formGroup]="todoForm" (ngSubmit)="updateTodo(todoForm.value)">
              <div class="form-group">
                <label class="col-md-4">Title </label>
                <input type="text" class="form-control" formControlName="title" />
              </div>
              <div class="form-group">
                <button type="submit" class="btn btn-primary col-md-4" [disabled]="todoForm.invalid">Update</button>
                <a [routerLink]="['/']">
                  <button type="submit" class="btn btn-primary col-md-4 ml-1">Back</button>
                </a>
              </div>
            </form>
          </div>
      </div>
  </div>
</div>

Open src/app/todo-edit.component.ts and put the below code

import { Component, OnInit } from '@angular/core';
import {FormBuilder, FormGroup, Validators, NgForm} from "@angular/forms";
import { ApiService } from '../api.service';
import { ActivatedRoute, Router } from '@angular/router';

import { Todo } from '../todo';

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

  todoForm: FormGroup;
  id:number= null;

  constructor(
    private formBuilder: FormBuilder, 
    private activeAouter: ActivatedRoute, 
    private router: Router, 
    private api: ApiService
  ) { }

  ngOnInit() {
    
    this.getDetail(this.activeAouter.snapshot.params['id']);

    this.todoForm = this.formBuilder.group({
      title: ['', Validators.compose([Validators.required])],
    });
  }

  getDetail(id) {
    this.api.getTodo(id)
      .subscribe(data => {
        this.id = data.id;
        this.todoForm.setValue({
          title: data.title
        });
        console.log(data);
      });
  }
  updateTodo(form:NgForm) {

    this.api.updateTodo(this.id, form)
      .subscribe(res => {
          this.router.navigate(['/']);
        }, (err) => {
          console.log(err);
        }
      );
    
  }

}

Configure the HttpClientModule

We need HttpClientModule to access RESTful API. So before creating a service, first, Open src/app/app.module.ts then add this import.

import { HttpClientModule } from '@angular/common/http';

Add HttpClientModule to imports array under @NgModule

imports: [
    HttpClientModule
]

Create Angular 8 Service for Accessing RESTful API

Generate an Angular 8 service for Accessing RESTful API by typing this command.

 ng g service api 

Next, open and edit src/app/api.service.ts then add the below function.

  getTodos (): Observable<Todo[]> {
    return this.http.get<Todo[]>(apiUrl, httpOptions)
      .pipe(
        tap(heroes => console.log('fetched todos')),
        catchError(this.handleError('getTodos', []))
      );
  }

  getTodo(id: number): Observable<Todo> {
    const url = `${apiUrl}?id=${id}`;
    return this.http.get<Todo>(url).pipe(
      tap(_ => console.log(`fetched todo id=${id}`)),
      catchError(this.handleError<Todo>(`getTodo id=${id}`))
    );
  }
  
  addTodo (todo): Observable<Todo> {
    
    return this.http.post<Todo>(`${apiUrl}/create.php`, todo, httpOptions).pipe(
      tap((todo: Todo) => console.log(`added todo w/ id=${todo.id}`)),
      catchError(this.handleError<Todo>('addTodo'))
    );
  }
  
  updateTodo (id, todo): Observable<any> {
    const url = `${apiUrl}/update.php?id=${id}`;
    return this.http.put(url, todo, httpOptions).pipe(
      tap(_ => console.log(`updated todo id=${id}`)),
      catchError(this.handleError<any>('updateTodo'))
    );
  }
  
  deleteTodo (id): Observable<Todo> {
    const url = `${apiUrl}/delete.php?id=${id}`;
  
    return this.http.delete<Todo>(url, httpOptions).pipe(
      tap(_ => console.log(`deleted todo id=${id}`)),
      catchError(this.handleError<Todo>('deletetodo'))
    );
  }
  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
  
      // TODO: send the error to remote logging infrastructure
      console.error(error); // log to console instead
  
      // Let the app keep running by returning an empty result.
      return of(result as T);
    };
  }

Run the below command, will run the Angular 8 Web Application and open the Application in browser by it self

ng serve -o

You may like

  1. Crud PHP MySQL Bootstrap Example Tutorial
  2. Laravel 6 CRUD Example Tutorial (Step By Step)
  3. Laravel 6 Ajax CRUD(DataTables Js) Tutorial Example
  4. First Codeigniter 3 CRUD (Create,Read,Update,Delete) via Mysql
  5. Codeigniter 3 Create First Ajax CRUD Application
  6. Node Express Js Creating a RESTful Crud Api With Mysql
  7. Laravel 6 Angular JS CRUD Example Tutorial

The Angular 8 crud Todo operation application will look like

angular crud add operation
angular crud add operation
angular  crud to do update operation
angular crud to do update operation
angular list to to crud operation
angular list to to crud operation

Leave a Reply

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