Angular 9 CRUD Application Example

By Hardik Savani | May 16, 2020 | Category : Angular


Hi Guys,

In this tutorial, i would like to show you step by step crud operations in angular 9 application. i will give you very simple example of angular 9 crud application. we will create angular 9 bootstrap crud operation uaing web api.

As we know, currently angular 9 version is released a few months ago. angular 9 provide more feature and improvements. so if you are new or you want to learn crud app in angular then this post will help you to build crud operation in angular 9.

If you are new, you don't know how to create first project of angular 9 and how to upgrade angular 8 to angular 9 then bellow tutorial can help you:

Create First App with Angular 9

Upgrade Angular 8 to Angular 9

Now, i don't want to confuse here, i will go strait step by step. you need to just follow few step to build crud app in angular application. After completed all steps, you can see layout like as bellow preview.

In this example we will create post crud module with list, view, insert, update and delete post. we will use web service api of jsonplaceholder. so we can easily use their created api. jsonplaceholder provide all apis that we require like list, view, create, delete and update.

Home Page:

Create Page:

Edit Page:

Detail Page:

Now, let's follow bellow step to creating crud app with angular 9.

Step 1: Create New App

We are going from scratch, so first install fresh angular application using bellow command, let's run bellow command:

ng new my-crud-app

Step 2: Install Bootstrap

now, we will install bootstrap for our crud application, so let's run bellow command and import it to css file.

npm install bootstrap --save

Now, let's import css file as like bellow:

src/styles.css

/* You can add global styles to this file, and also import other style files */

@import "~bootstrap/dist/css/bootstrap.css";

Step 3: Create Post Module

After creating successfully app, we need to create post module using angular cli command. angular provide command to create module with routing in angular application. so let's run bellow command to create post module:

ng generate module post --routing

run successfully command, it will create files as like bellow path:

src/app/post/post.module.ts

src/app/post/post-routing.module.ts

Step 4: Create Component For Module

Now we will add new component to our post module using bellow command, so let's create index, view, create and edit component for admin module:

ng generate component post/index

ng generate component post/view

ng generate component post/create

ng generate component post/edit

run successfully command, it will create folder with files as like bellow path:

src/app/post/index/*

src/app/post/view/*

src/app/post/create/*

src/app/post/edit/*

Step 5: Create Route

In this step, we will simply create route for index, create, edit and view using generated new component. so we have to update our post-routing module file as like bellow code:

src/app/post/post-routing.module.ts

import { NgModule } from '@angular/core';

import { Routes, RouterModule } from '@angular/router';

import { IndexComponent } from './index/index.component';

import { ViewComponent } from './view/view.component';

import { CreateComponent } from './create/create.component';

import { EditComponent } from './edit/edit.component';

const routes: Routes = [

{ path: 'post', redirectTo: 'post/index', pathMatch: 'full'},

{ path: 'post/index', component: IndexComponent },

{ path: 'post/:postId/view', component: ViewComponent },

{ path: 'post/create', component: CreateComponent },

{ path: 'post/:postId/edit', component: EditComponent }

];

@NgModule({

imports: [RouterModule.forChild(routes)],

exports: [RouterModule]

})

export class PostRoutingModule { }

Step 6: Create Interface

in this step, we will create interface using angular command for post module. we will use post interface with Observable. so let's create interface with bellow code.

ng generate interface post/post

src/app/post/post.ts

export interface Post {

id: number;

title: string;

body: string;

}

Step 7: Create Services

Here, we will create post service file and we will write and call all web services. we will create getAll(), create(), find(), update() and delete().

we are using https://jsonplaceholder.typicode.com web site api for now. they provide to easily use. But if you want to create your own api with PHP then bellow link can help you.

Create Web Service using PHP Laravel

Create Web Service using PHP Codeigniter

Now, let's create post service and put all code for web service method.

ng generate service post/post

src/app/post/post.service.ts

import { Injectable } from '@angular/core';

import { HttpClient, HttpHeaders } from '@angular/common/http';

import { Observable, throwError } from 'rxjs';

import { catchError } from 'rxjs/operators';

import { Post } from './post';

@Injectable({

providedIn: 'root'

})

export class PostService {

private apiURL = "https://jsonplaceholder.typicode.com";

httpOptions = {

headers: new HttpHeaders({

'Content-Type': 'application/json'

})

}

constructor(private httpClient: HttpClient) { }

getAll(): Observable<Post[]> {

return this.httpClient.get<Post[]>(this.apiURL + '/posts/')

.pipe(

catchError(this.errorHandler)

)

}

create(post): Observable<Post> {

return this.httpClient.post<Post>(this.apiURL + '/posts/', JSON.stringify(post), this.httpOptions)

.pipe(

catchError(this.errorHandler)

)

}

find(id): Observable<Post> {

return this.httpClient.get<Post>(this.apiURL + '/posts/' + id)

.pipe(

catchError(this.errorHandler)

)

}

update(id, post): Observable<Post> {

return this.httpClient.put<Post>(this.apiURL + '/posts/' + id, JSON.stringify(post), this.httpOptions)

.pipe(

catchError(this.errorHandler)

)

}

delete(id){

return this.httpClient.delete<Post>(this.apiURL + '/posts/' + id, this.httpOptions)

.pipe(

catchError(this.errorHandler)

)

}

errorHandler(error) {

let errorMessage = '';

if(error.error instanceof ErrorEvent) {

errorMessage = error.error.message;

} else {

errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;

}

return throwError(errorMessage);

}

}

Step 8: Update Component Logic and Template

Now in this step, we will work on our created component for crud application. we create four component for our crud application. now we will go one by one for creating list page, create page, edit page and view page.

so, let's see one by one:


1) List Page Template and Component

now, here we will work on post index component. we will call post service and display it with create, edit, delete and view button. so let's update it.

src/app/post/index/index.component.ts

import { Component, OnInit } from '@angular/core';

import { PostService } from '../post.service';

import { Post } from '../post';

@Component({

selector: 'app-index',

templateUrl: './index.component.html',

styleUrls: ['./index.component.css']

})

export class IndexComponent implements OnInit {

posts: Post[] = [];

constructor(public postService: PostService) { }

ngOnInit(): void {

this.postService.getAll().subscribe((data: Post[])=>{

this.posts = data;

console.log(this.posts);

})

}

deletePost(id){

this.postService.delete(id).subscribe(res => {

this.posts = this.posts.filter(item => item.id !== id);

console.log('Post deleted successfully!');

})

}

}

src/app/post/index/index.component.html

<div class="container">

<h1>Angular CRUD Example - ItSolutionStuff.com</h1>

<a href="#" routerLink="/post/create/" class="btn btn-success">Create New Post</a>

<table class="table table-bordered">

<tr>

<th>ID</th>

<th>Title</th>

<th>Body</th>

<th width="220px">Action</th>

</tr>

<tr *ngFor="let post of posts">

<td>{{ post.id }}</td>

<td>{{ post.title }}</td>

<td>{{ post.body }}</td>

<td>

<a href="#" [routerLink]="['/post/', post.id, 'view']" class="btn btn-info">View</a>

<a href="#" [routerLink]="['/post/', post.id, 'edit']" class="btn btn-primary">Edit</a>

<button type="button" (click)="deletePost(post.id)" class="btn btn-danger">Delete</button>

</td>

</tr>

</table>

</div>

You will see preview as like bellow:


2) Create Page Template and Component

now here, we will use reactive form store data into server using web services. so let's update it.

src/app/post/create/create.component.ts

import { Component, OnInit } from '@angular/core';

import { PostService } from '../post.service';

import { Router } from '@angular/router';

import { FormGroup, FormControl, Validators} from '@angular/forms';

@Component({

selector: 'app-create',

templateUrl: './create.component.html',

styleUrls: ['./create.component.css']

})

export class CreateComponent implements OnInit {

form: FormGroup;

constructor(

public postService: PostService,

private router: Router

) { }

ngOnInit(): void {

this.form = new FormGroup({

title: new FormControl('', [Validators.required]),

body: new FormControl('', Validators.required)

});

}

get f(){

return this.form.controls;

}

submit(){

console.log(this.form.value);

this.postService.create(this.form.value).subscribe(res => {

console.log('Post created successfully!');

this.router.navigateByUrl('post/index');

})

}

}

src/app/post/create/create.component.html

<div class="container">

<h1>Create New Post</h1>

<a href="#" routerLink="/post/index" class="btn btn-primary">Back</a>

<form [formGroup]="form" (ngSubmit)="submit()">

<div class="form-group">

<label for="title">Title:</label>

<input

formControlName="title"

id="title"

type="text"

class="form-control">

<div *ngIf="f.title.touched && f.title.invalid" class="alert alert-danger">

<div *ngIf="f.title.errors.required">Title is required.</div>

</div>

</div>

<div class="form-group">

<label for="body">Body</label>

<textarea

formControlName="body"

id="body"

type="text"

class="form-control">

</textarea>

<div *ngIf="f.body.touched && f.body.invalid" class="alert alert-danger">

<div *ngIf="f.body.errors.required">Body is required.</div>

</div>

</div>

<button class="btn btn-primary" type="submit" [disabled]="!form.valid">Submit</button>

</form>

</div>

You will see preview as like bellow:


3) Edit Page Template and Component

now here, we will use reactive form store data into server using web services for update post information. so let's update it.

src/app/post/edit/edit.component.ts

import { Component, OnInit } from '@angular/core';

import { PostService } from '../post.service';

import { ActivatedRoute, Router } from '@angular/router';

import { Post } from '../post';

import { FormGroup, FormControl, Validators} from '@angular/forms';

@Component({

selector: 'app-edit',

templateUrl: './edit.component.html',

styleUrls: ['./edit.component.css']

})

export class EditComponent implements OnInit {

id: number;

post: Post;

form: FormGroup;

constructor(

public postService: PostService,

private route: ActivatedRoute,

private router: Router

) { }

ngOnInit(): void {

this.id = this.route.snapshot.params['postId'];

this.postService.find(this.id).subscribe((data: Post)=>{

this.post = data;

});

this.form = new FormGroup({

title: new FormControl('', [Validators.required]),

body: new FormControl('', Validators.required)

});

}

get f(){

return this.form.controls;

}

submit(){

console.log(this.form.value);

this.postService.update(this.id, this.form.value).subscribe(res => {

console.log('Post updated successfully!');

this.router.navigateByUrl('post/index');

})

}

}

src/app/post/edit/edit.component.html

<div class="container">

<h1>Update Post</h1>

<a href="#" routerLink="/post/index" class="btn btn-primary">Back</a>

<form [formGroup]="form" (ngSubmit)="submit()">

<div class="form-group">

<label for="title">Title:</label>

<input

formControlName="title"

id="title"

type="text"

[(ngModel)]="post.title"

class="form-control">

<div *ngIf="f.title.touched && f.title.invalid" class="alert alert-danger">

<div *ngIf="f.title.errors.required">Title is required.</div>

</div>

</div>

<div class="form-group">

<label for="body">Body</label>

<textarea

formControlName="body"

id="body"

type="text"

[(ngModel)]="post.body"

class="form-control">

</textarea>

<div *ngIf="f.body.touched && f.body.invalid" class="alert alert-danger">

<div *ngIf="f.body.errors.required">Body is required.</div>

</div>

</div>

<button class="btn btn-primary" type="submit" [disabled]="!form.valid">Update</button>

</form>

</div>

You will see preview as like bellow:


4) Detail Page Template and Component

now here, we will display data into server using web services for update post information. so let's update it.

src/app/post/view/view.component.ts

import { Component, OnInit } from '@angular/core';

import { PostService } from '../post.service';

import { ActivatedRoute, Router } from '@angular/router';

import { Post } from '../post';

@Component({

selector: 'app-view',

templateUrl: './view.component.html',

styleUrls: ['./view.component.css']

})

export class ViewComponent implements OnInit {

id: number;

post: Post;

constructor(

public postService: PostService,

private route: ActivatedRoute,

private router: Router

) { }

ngOnInit(): void {

this.id = this.route.snapshot.params['postId'];

this.postService.find(this.id).subscribe((data: Post)=>{

this.post = data;

});

}

}

src/app/post/view/view.component.html

<div class="container">

<h1>View Post</h1>

<a href="#" routerLink="/post/index" class="btn btn-primary">Back</a>

<div>

<strong>ID:</strong>

<p>{{ post.id }}</p>

</div>

<div>

<strong>Title:</strong>

<p>{{ post.title }}</p>

</div>

<div>

<strong>Body:</strong>

<p>{{ post.body }}</p>

</div>

</div>

You will see preview as like bellow:

Step 9: Import to Module File

Now in last step, we will import our post module and HttpClientModule to main file and also other to post module.

src/app/app.module.ts

import { BrowserModule } from '@angular/platform-browser';

import { NgModule } from '@angular/core';

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

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

import { AppComponent } from './app.component';

import { PostModule } from './post/post.module';

@NgModule({

declarations: [

AppComponent

],

imports: [

BrowserModule,

AppRoutingModule,

PostModule,

HttpClientModule

],

providers: [],

bootstrap: [AppComponent]

})

export class AppModule { }

src/app/post/post.module.ts

import { NgModule } from '@angular/core';

import { CommonModule } from '@angular/common';

import { PostRoutingModule } from './post-routing.module';

import { IndexComponent } from './index/index.component';

import { ViewComponent } from './view/view.component';

import { CreateComponent } from './create/create.component';

import { EditComponent } from './edit/edit.component';

import { FormsModule, ReactiveFormsModule } from '@angular/forms';

@NgModule({

declarations: [IndexComponent, ViewComponent, CreateComponent, EditComponent],

imports: [

CommonModule,

PostRoutingModule,

FormsModule,

ReactiveFormsModule

]

})

export class PostModule { }

Now we are ready to run our example, you can run by following command:

ng serve

You will have layout like as bellow.

I hope it can help you...




Hardik Savani
My name is Hardik Savani. I'm a full-stack developer, entrepreneur and owner of Aatman Infotech. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Javascript, JQuery, Laravel, Codeigniter, VueJS, AngularJS and Bootstrap from the early stage.
Follow Me: Github Twitter
***Do you want me hire for your Project Work? Then Contact US.

We are Recommending you: