In this post, we will see how to create a project in Angular to manage CRUD (Create, Read, Update and Delete) operations for an entity called User; we will use Json Server for the definition of a Web API service.
WEB API
We create a file called UsersDB where we will define a list of User entities:
[USERS.DB]
{
"users": [
{
"id": 1,
"surname": "Surname1",
"name": "Name1"
},
{
"id": 2,
"surname": "Surname2",
"name": "Name2"
},
{
"id": 3,
"surname": "Surname3",
"name": "Name3"
}
]
}
Now, in order to start Json Server, we run the command:
json-server --watch UsersDB.json
ANGULAR PROJECT
We start defining a new project called UsersCore:
ng new UsersCore
Then, with the command ng serve, we will run the application:
Now, we create an interface called User and a service called Core, used to define all CRUD operations:
ng g i model/user
ng g s service/core
[USER.TS]
export interface User {
id?: number;
surname: string;
name: string
}
[CORE.TS]
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { User } from '../model/user';
import { HttpClient, HttpHeaders } from '@angular/common/http';
// We define the httOptions that we will use in the POST and PUT operations
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
}),
};
@Injectable({
providedIn: 'root'
})
export class CoreService {
// we define the url of the Web API service
private apiUrl: string = "http://localhost:3000/users";
// we inject the HttpClient
constructor(private service: HttpClient) { }
// definition of Get operation
GetUsers():Observable<User[]>{
return this.service.get<User[]>(this.apiUrl);
}
// definition of Delete operation
DeleteUser(user:User): Observable<User>{
// we pass the User's Id
const url = `${this.apiUrl}/${user.id}`;
return this.service.delete<User>(url);
}
// definition of Update operation
UpdateUser(user:User): Observable<User>{
// we pass the User's Id
const url = `${this.apiUrl}/${user.id}`;
// We use httpOptions, because we are passing an object
return this.service.put<User>(url, user, httpOptions);
}
// definition of Insert operation
AddUser(user:User): Observable<User>{
// We use httpOptions, because we are passing an object
return this.service.post<User>(this.apiUrl, user, httpOptions);
}
}
Now, we define three components:
1) Header component where we will add the application’s title and a button for adding a new user
2) Users component to display the list of Users
3) UserItem component to display and delete the single User:
ng g c components/header
ng g components/users
ng g c components/useritem
[HEADER.HTML]
<header>
<h1>Users</h1>
<a routerLink="/manageuser" class="btn" [ngStyle]="{'background-color': 'green'}">Add User</a>
</header>
[USERS.HTML]
<app-useritem *ngFor="let user of users" [user]="user" (onDeleteUser)="deleteUser(user)"></app-useritem>
[USERS.TS]
import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { CoreService } from 'src/app/service/core.service';
@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.css']
})
export class UsersComponent implements OnInit {
users: User[] = [];
// we inject the CoreService
constructor(private userService: CoreService) { }
ngOnInit(): void {
// in the Init function, we call the GetUsers method
this.userService.GetUsers().subscribe(usersOutput => {
this.users = usersOutput
});
}
deleteUser(user: User)
{
this.userService.DeleteUser(user).subscribe(() => {
this.users = this.users.filter(t => t.id!== user.id);
});
}
}
[USERITEM.HTML]
<div class="user">
<h3>{{ user.surname }}</h3>
<p>{{ user.name }}</p>
<button class="btn" [ngStyle]="{'background-color': 'red'}" (click)="onDelete(user)" >Delete</button>
<button class="btn" [ngStyle]="{'background-color': 'orange'}" (click)="onUpdate(user)" >Update</button>
</div>
[USERITEM.TS]
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { User } from 'src/app/model/user';
import { Router, NavigationExtras } from '@angular/router';
@Component({
selector: 'app-useritem',
templateUrl: './useritem.component.html',
styleUrls: ['./useritem.component.css']
})
export class UseritemComponent implements OnInit {
@Input() user!:User;
@Output() onDeleteUser: EventEmitter<User> = new EventEmitter();
// we inject Router used to pass the value at the manageuser component
constructor(private router: Router) { }
ngOnInit(): void {
}
onDelete(user: User){
this.onDeleteUser.emit(user);
}
onUpdate(user: User)
{
let navigationExtras: NavigationExtras = {
queryParams: {
Name: user.name,
Surname: user.surname,
Id: user.id
}
};
// we pass the NavigationExtras in the route.navigate
this.router.navigate(["manageuser"], navigationExtras);
}
}
Then, we create a new component called manage-user to manage a user:
ng g c components/manage-user
[MANAGE-USER.HTML]
<form class="add-form" (ngSubmit)="onSubmit()">
<div class="form-control">
<label for="surname">Surname</label>
<input type="text" name="surname" id="surname" placeholder="Insert surname" [(ngModel)] = "surname" />
</div>
<div class="form-control">
<label for="name">Name</label>
<input type="text" name="name" id="name" placeholder="Insert name" [(ngModel)] = "name" />
</div>
<div class="btn-group">
<input type="submit" value="Save User" class="btn" style="width: 110px;">
<a routerLink="/users" class="btn" [ngStyle]="{'background-color': 'red'}">Cancel</a>
</div>
</form>
[MANAGE-USER.TS]
import { Component, OnInit, Input } from '@angular/core';
import { User } from 'src/app/model/user';
import { CoreService } from 'src/app/service/core.service';
import { Router, ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-manage-user',
templateUrl: './manage-user.component.html',
styleUrls: ['./manage-user.component.css']
})
export class ManageUserComponent implements OnInit {
id?:number;
surname: string = "";
name: string ="";
// we inject userService used to call the AddUser and UpdateUser methods
// router is used to redirect the page at the list of users
// activatedRoute is used to get the parameters from the previuos page, in case of update
constructor(private userService: CoreService, private router: Router, private activatedRoute: ActivatedRoute){
// using activatedRoute we can get the parameters
// that we put in the previous page
this.activatedRoute.queryParams.subscribe(params => {
this.name = params['Name'];
this.surname = params['Surname'];
this.id = params['Id'];
});
}
ngOnInit(): void {
}
onSubmit(){
if(!this.surname || !this.name)
{
alert('Please insert Surname and Name!');
return
}
const outputUser: User = {
name: this.name,
surname: this.surname
};
if(this.id === undefined)
{
// new user
this.userService.AddUser(outputUser).subscribe();
}
else
{
// update user
outputUser.id = this.id;
this.userService.UpdateUser(outputUser).subscribe();
}
// redirect to the Users list page
this.router.navigate(['/']);
}
}
Finally, we have to modify other two files:
[APP-ROUTING.TS]
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { UsersComponent } from './components/users/users.component';
import { ManageUserComponent } from './components/manage-user/manage-user.component';
const routes: Routes = [
{ path: '', pathMatch: 'full', redirectTo: 'users'},
{ path: 'users', component: UsersComponent },
{ path: 'manageuser', component: ManageUserComponent }
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
[APP.MODULE.TS]
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http'
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { UsersComponent } from './components/users/users.component';
import { UseritemComponent } from './components/useritem/useritem.component';
import { ManageUserComponent } from './components/manage-user/manage-user.component';
@NgModule({
declarations: [
AppComponent,
HeaderComponent,
UsersComponent,
UseritemComponent,
ManageUserComponent
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
We have done and now, if we run the application, this will be the result:
LIST OF USERS
NEW USER
UPDATE USER
DELETE USER
CRUD operations – CODE
https://github.com/ZoneOfDevelopment/AngularCRUDOperations