CRUD Operations in Angular

In this tutorial, we will be developing an angular application and perform CRUD operations in angular. CRUD operations include POST, GET, UPDATE and DELETE requests respectively. In this tutorial, you will learn how to implement CRUD operations in an angular step by step.

Creating angular application:

Create angular application by using following command.

ng new crud-app-in-angular

Your angular application will get created with this command.
Now put the following code in the app.component.ts file.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  constructor() { }
  title = 'CRUD operations in angular';

  ngOnInit() {
  }
}

Put following code in app.component.html file.

<div style="text-align:center; margin-bottom: 24px">
  <h1>
    {{ title }}!
  </h1>
</div>

By changing code from above file, we have changed the title to “CRUD operations in angular”.

Adding Bootstrap CSS framework:

Add Bootstrap CSS framework into the angular application for easily applying styles. Adding bootstrap is optional. You can learn how to add bootstrap in angular with this article: Install Bootstrap in angular.

Adding FontAwesome in angular:

To add icons in this crud operations in angular project, lets add FontAwesome into project. To add FontAwesome in angular simply add following link tag in index.html file.

<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.0/css/all.css"
    integrity="sha384-lZN37f5QGtY3VHgisS14W3ExzMWZxybE1SJSEsQp9S+oqd12jhcu+A56Ebc1zFSJ" crossorigin="anonymous">

You can also learn how to install it with this article: Installing FontAwesome in Angular

Creating User Component:

Create new component named as user with the following command.

ng generate component user

OR using short command like following.

ng g c user

We will implement all crud operations using this newly created user component.

Put following code in app.component.html file. Here I have called the selector of user component which will load into app component.

<div style="text-align:center; margin-bottom: 24px">
  <h1>
    {{ title }}!
  </h1>
</div>
<app-user></app-user>

Creating userdata service:

Create userdata service with following command.

ng generate service userdata

OR using short command like following.

ng g s userdata

We will use this service to send request such as GET, POST, PUT, and DELETE to perform CRUD operations on user data.

CRUD operations in angular:

For implementing CRUD operations in angular, put the following code into respective files as suggested. After this, you can learn the code explanation.
Here, you will learn how to use service to make requests to the server. In the following code, I made a call to the JSONPlaceholder website which provides fake online REST API for testing and prototyping purposes. I created functions in service and made calls to perform CRUD operations on data.

Put the following code in userdata.service.ts file.

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

@Injectable({
  providedIn: 'root'
})
export class UserdataService {

  constructor(private http: HttpClient) { }

  getUserData() {
    const url = 'https://jsonplaceholder.typicode.com/users';
    return this.http.get(url);
  }

  createUser(userData) {
    const url = 'https://jsonplaceholder.typicode.com/users';
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json; charset=UTF-8'
      })
    };

    return this.http.post(url, userData, httpOptions);
  }

  deleteUser(userData) {
    const url = `https://jsonplaceholder.typicode.com/users/${userData.id}`;
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json; charset=UTF-8'
      })
    };
    return this.http.delete(url, httpOptions);
  }

  editUser(userData) {
    const url = `https://jsonplaceholder.typicode.com/users/${userData.id}`;
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type': 'application/json; charset=UTF-8'
      })
    };

    return this.http.put(url, userData, httpOptions);
  }
}

Put following code in user.component.ts file

import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, FormBuilder } from '@angular/forms';

import { UserdataService } from './userdata.service';

@Component({
  selector: 'app-user',
  templateUrl: './user.component.html',
  styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
  userData;
  userForm: FormGroup;
  editUserForm: FormGroup;
  showEditUserForm = false;
  editFormId;

  // variables to status of request;
  userCreated = false;
  userEdited = false;
  userDeleted = false;
  userDeletedId;
  constructor(private userDataService: UserdataService, private fb: FormBuilder) { }

  ngOnInit() {
    this.userDataService.getUserData().subscribe((data) => {
      console.log('data', data);
      this.userData = data;
    });

    this.initForm();
  }

  initForm() {
    this.userForm = this.fb.group({
      name: [],
      username: [],
      email: []
    });
  }

  createUser(event, userform) {
    const userData = userform.value;
    this.userDataService.createUser(userData).subscribe((data) => {
      console.log('user created', data);
      this.userCreated = true;
      setTimeout(() => {
        this.userCreated = false;
      }, 2000);
    });
  }

  editUser(event, data) {
    this.showEditUserForm = true;
    this.editFormId = data.Id;
    this.editUserForm = this.fb.group({
      id: [data.id],
      name: [data.name],
      username: [data.username],
      email: [data.email]
    });
  }

  editUserData(event, userform) {
    const userData = userform.value;
    this.userDataService.editUser(userData).subscribe((data) => {
      console.log('user edited', data);
      this.userEdited = true;
      setTimeout(() => {
        this.userEdited = false;
        this.showEditUserForm = false;
      }, 2000);
    });
  }

  deleteUser(event, userData) {
    this.userDataService.deleteUser(userData).subscribe((data) => {
      console.log('user deleted', data);
      this.userDeletedId = userData.id;
      this.userDeleted = true;
      setTimeout(() => {
        this.userDeleted = false;
      }, 2000);
    });
  }
}

Put following code in user.component.html file.

<div *ngIf="!showEditUserForm" class="container">
  <div class="create-block">
    <div>
      <h3>Create User:</h3>
    </div>
    <form [formGroup]="userForm" (submit)="createUser($event, userForm)">
      <div class="form-group row">
        <label class="col-sm-3" for="name">Name:</label>
        <input class="col-sm-9" type="text" placeholder="Enter name" id="email" formControlName="name">
      </div>
      <div class="form-group row">
        <label class="col-sm-3" for="username">Username:</label>
        <input class="col-sm-9" type="text" placeholder="Enter username" id="username" formControlName="username">
      </div>
      <div class="form-group row">
        <label class="col-sm-3" for="email">Email address:</label>
        <input class="col-sm-9" type="email" placeholder="Enter email" id="email" formControlName="email">
      </div>

      <button class="btn btn-primary" type="submit">
        <i class="fas fa-plus"></i> Create User
      </button>
    </form>

    <div class="status" *ngIf="userCreated">
      User Created Sucessfully.
    </div>
  </div>
</div>

<div *ngIf="userData">
  <h3 class="text-center">User Data</h3>
  <div class="container" *ngFor="let data of userData">
    <div *ngIf="!showEditUserForm" class="user-data card">
      <div>
        <div>
          <h4> Name: {{data.name}}</h4>
        </div>
        <div>
          <h4> Username: {{data.username}}</h4>
        </div>
        <div>
          <h4> Email: {{data.email}}</h4>
        </div>
      </div>
      <div>
        <button style="margin: 4px;" class="btn btn-primary" (click)="editUser($event, data)">
          <i class="fas fa-edit"></i> Edit User
        </button>
        <button style="margin: 4px;" class="btn btn-danger" (click)="deleteUser($event, data)">
          <i class="fas fa-trash"></i> Delete User
        </button>
      </div>

      <div>
        <div class="status" *ngIf="userDeleted && data.id === userDeletedId">
          User Deleted Sucessfully.
        </div>
      </div>
    </div>
  </div>

  <div class="container" *ngIf="showEditUserForm">
    <div class="create-block">
      <div>
        <h3>Edit User:</h3>
      </div>
      <form [formGroup]="editUserForm" (submit)="editUserData($event, editUserForm)">
        <div class="form-group row">
          <label class="col-sm-3" for="name">Name:</label>
          <input class="col-sm-9" type="text" placeholder="Enter name" id="email" formControlName="name">
        </div>
        <div class="form-group row">
          <label class="col-sm-3" for="username">Username:</label>
          <input class="col-sm-9" type="text" placeholder="Enter username" id="username" formControlName="username">
        </div>
        <div class="form-group row">
          <label class="col-sm-3" for="email">Email address:</label>
          <input class="col-sm-9" type="email" placeholder="Enter email" id="email" formControlName="email">
        </div>

        <button class="btn btn-primary" type="submit">Edit User</button>
      </form>

      <div class="status" *ngIf="userEdited">
        User Edited Sucessfully.
      </div>
    </div>
  </div>
</div>

Put following code in user.component.css file for style purposes.

.user-data {
  width: 100%;
  padding: 24px;
  margin-bottom: 24px;
  box-shadow: 0 2px 1px -1px rgba(0,0,0,.2), 0 1px 1px 0 rgba(0,0,0,.14), 0 1px 3px 0 rgba(0,0,0,.12);
}

.info-block {
  display: flex;
}

.create-block {
  padding: 24px;
  border: 1px solid grey;
  border-radius: 5px;
  margin-bottom: 24px;
}

.status {
  padding: 8px;
  background: #0b990b;
  color: white;
  margin-top: 8px;
  border: 1px solid black;
  border-radius: 5px;
}

Put following code into app.module.ts file.

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

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http';
import { UserComponent } from './user/user.component';
import { ReactiveFormsModule, FormsModule } from '@angular/forms';

@NgModule({
  declarations: [
    AppComponent,
    UserComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    FormsModule,
    ReactiveFormsModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Output:

Run your project and you can perform CRUD operations on data that we fetched from the JSONPlaceholder website. See the following images of the output of CRUD operations.

GET operation output:

CREATE operation output:

Update operation output:

DELETE operation output:

Code Explanation:

From the following points, you will learn how to CREATE, READ, UPDATE and DELETE operation are done in the above code with an explanation.

**Note:-

As the JSONPlaceholder website provides fake online REST API for testing and prototyping purposes, the requests we made like POST, PUT, DELETE will not actually insert, modify or delete data into the server. But as you can see that from the above images of dev tools and console logs, the requests gets performed successfully.

READ operation:

To read data from the server, you have to perform a GET request to the server. To make HTTP requests, you have to import angular’s built-in HttpClientModule into AppModule. This module will be helpful for making HTTP requests.
I have made a function that makes GET request to the server for fetching data.

getUserData() {
    const url = 'https://jsonplaceholder.typicode.com/users';
    return this.http.get(url);
  }

This function return data fetched from server. To access data from this function, I have made call to this function from user component.

 this.userDataService.getUserData().subscribe((data) => {
    console.log('data', data);
    this.userData = data;
  });

I stored data received from server into userData variable. To display data from server I have performed for loop on userData and displayed the userData like name, username and email.

<div class="container" *ngFor="let data of userData">
  <div class="user-data card">
    <div>
      <div>
        <h4> Name: {{data.name}}</h4>
      </div>
      <div>
        <h4> Username: {{data.username}}</h4>
      </div>
      <div>
        <h4> Email: {{data.email}}</h4>
      </div>
    </div>
  </div>
</div>

CREATE operation:

For CREATE operation, we have to send POST request to the server. Here, to create a user into server, I have made POST request to the server. To create a user, I made createUser function which gets required data from user component when user fills a form. Then createUser function sends POST request to the server.

I have created a userForm where information has to be filled to create a user into server. When user fills that form and clicks on Create User button, it sends data to following function.

createUser(event, userform) {
  const userData = userform.value;
  this.userDataService.createUser(userData).subscribe((data) => {
    console.log('user created', data);
  });
}

This createUser function from user component makes a call to the createUser function from userData service. This createUser function from userData service makes a POST request to the server.

createUser(userData) {
  const url = 'https://jsonplaceholder.typicode.com/users';
  const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json; charset=UTF-8'
    })
  };

  return this.http.post(url, userData, httpOptions);
}

UPDATE operation:

To update or modify certain data, we have to make a PUT request to the server. I have created an editUserForm where information has to be filled to edit a user from the server. For UPDATE operation, editUserData function from user component gets data when a user fills a form and clicks on the Edit User button.

editUserData(event, userform) {
  const userData = userform.value;
  this.userDataService.editUser(userData).subscribe((data) => {
    console.log('user edited', data);
  });
}

This editUserData function send data to editUser function from userData service. editUser function from userData service makes PUT request to server. To make PUT request for particular user data, you have to send PUT request to that particular user data only. Like in below editUser function, I have passed the id of the user data which is being edited into url.

editUser(userData) {
  const url = `https://jsonplaceholder.typicode.com/users/${userData.id}`;
  const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json; charset=UTF-8'
    })
  };

  return this.http.put(url, userData, httpOptions);
}

For good user interface, I have only shown the edit user form when user clicks on Edit User button. Also I hide that edit form when PUT request gets sucessfully performed. For this I have made showEditUserForm variable true when user clicks Edit User button. To hide edit user form I have set showEditUserForm variable to false when PUT request gets sucessfully performed.

Delete operation:

For DELETE operation, we have make DELETE request to the server. When user clicks Delete user button, data gets passed to deleteUser function from user component.

deleteUser(event, userData) {
  this.userDataService.deleteUser(userData).subscribe((data) => {
    console.log('user deleted', data);
    this.userDeletedId = userData.id;
    this.userDeleted = true;
    setTimeout(() => {
      this.userDeleted = false;
    }, 2000);
  });
}

deleteUser function from user component makes call to deleteUser from userData service which then makes DELETE request to the server. To make DELETE request, I have send id of user data which is to be deleted into the url.

deleteUser(userData) {
  const url = `https://jsonplaceholder.typicode.com/users/${userData.id}`;
  const httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json; charset=UTF-8'
    })
  };
  return this.http.delete(url, httpOptions);
}

Request Status:

To indicate when request gets sucessfully performed, I have used variables userCreated, userEdited, userDeleted, userDeletedId; After request gets sucessfully performed, I have set appropriate message regarding that operation.

Conclusion:

From this tutorial you learned how to perform CRUD operations in angular in detail. As this tutorial might get difficult for beginners to learn, post comments if you have any difficulty for implementing this application.

Leave a Reply

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