In this tutorial Angular 8 CRUD tutorial, we will learn how to implement CRUD To-do Application in Angular 8.
Befor get started with angular 8 crud operation. You must have installed Angular project.
So let’s get start:
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.
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' }
},
];
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.
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
],
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>
<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);
}
);
}
}
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);
});
}
}
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);
}
);
}
}
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
]
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
#Angular #webdev #javascript