Spring Boot + Angular 9 CRUD - Part 3 - Develop Angular 8 CRUD Operations

In the previous part 2, we have installed and created an Angular 9 web application. 

In this part 3 of Spring Boot + Angular 9 CRUD Example Tutorial, we will develop CRUD operations for an employee model using Angular 9.

Use below links to visit different parts of this tutorial:
  1. Spring Boot + Angular 9 CRUD Example Tutorial - Main Tutorial
  2. Spring Boot + Angular 9 CRUD Tutorial - Part 1 - Develop Spring Boot CRUD Rest APIs
  3. Spring Boot + Angular 9 CRUD - Part 2 - Create an Angular 9 App
  4. Spring Boot + Angular 9 CRUD - Part 3 - Develop Angular 9 CRUD Operations
  5. Spring Boot  + Angular 9 CRUD, Part 4 - Angular 9 CRUD App Configuration
  6. Spring Boot 2 + Angular 9 CRUD, Part 5 - Running Angular 9 CRUD App

Table of contents

  1. Create an Employee class
  2. Employee Service
  3. Creating Employee List Template and Component
  4. Create Add Employee Template and Component
  5. Update Employee Template and Component
  6. Create View Employee Details Template and Component
The below diagram summaries the Angular components that we are going to create going forward:

1. Create an Employee Model (TypeScript)

Path - src/app/employee.ts
Before defining the EmployeeListComponent, let’s define an Employee class for working with employees. create a new file employee.ts inside src/app folder and add the following code to it -
export class Employee {
    id: number;
    firstName: string;
    lastName: string;
    emailId: string;
    active: boolean;
}

2. Creating Employee List Template and Component

Employee List Component

Path - src/app/employee-list/employee-list.component.ts
Let's create EmployeeListComponent component which will be used to display a list of employees, create a new employee, and delete an employee.
Update/remove the content of employee-list.component.ts inside src/app directory and add the following code to it -
import { EmployeeDetailsComponent } from '../employee-details/employee-details.component';
import { Observable } from "rxjs";
import { EmployeeService } from "../employee.service";
import { Employee } from "../employee";
import { Component, OnInit } from "@angular/core";
import { Router } from '@angular/router';

@Component({
  selector: "app-employee-list",
  templateUrl: "./employee-list.component.html",
  styleUrls: ["./employee-list.component.css"]
})
export class EmployeeListComponent implements OnInit {
  employees: Observable<Employee[]>;

  constructor(private employeeService: EmployeeService,
    private router: Router) {}

  ngOnInit() {
    this.reloadData();
  }

  reloadData() {
    this.employees = this.employeeService.getEmployeesList();
  }

  deleteEmployee(id: number) {
    this.employeeService.deleteEmployee(id)
      .subscribe(
        data => {
          console.log(data);
          this.reloadData();
        },
        error => console.log(error));
  }

  employeeDetails(id: number){
    this.router.navigate(['details', id]);
  }
}

Employee List Template

Path - src/app/employee-list/employee-list.component.html 
Add employee-list.component.html file with the following code to it -
<div class="panel panel-primary">
  <div class="panel-heading">
    <h2>Employee List</h2>
  </div>
  <div class="panel-body">
    <table class="table table-striped">
      <thead>
        <tr>
          <th>Firstname</th>
          <th>Lastname</th>
          <th>Email</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody>
        <tr *ngFor="let employee of employees | async">
          <td>{{employee.firstName}}</td>
          <td>{{employee.lastName}}</td>
          <td>{{employee.emailId}}</td>
          <td><button (click)="deleteEmployee(employee.id)" class="btn btn-danger">Delete</button>
              <button (click)="employeeDetails(employee.id)" class="btn btn-info" style="margin-left: 10px">Details</button>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</div>

3. Create Add Employee Template and Component

Create Employee Component

Path - src/app/create-employee/create-employee.component.ts
CreateEmployeeComponent is used to create and handle a new employee form data.

Add the following code to CreateEmployeeComponent:
import { EmployeeService } from '../employee.service';
import { Employee } from '../employee';
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

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

  employee: Employee = new Employee();
  submitted = false;

  constructor(private employeeService: EmployeeService,
    private router: Router) { }

  ngOnInit() {
  }

  newEmployee(): void {
    this.submitted = false;
    this.employee = new Employee();
  }

  save() {
    this.employeeService
    .createEmployee(this.employee).subscribe(data => {
      console.log(data)
      this.employee = new Employee();
      this.gotoList();
    }, 
    error => console.log(error));
  }

  onSubmit() {
    this.submitted = true;
    this.save();    
  }

  gotoList() {
    this.router.navigate(['/employees']);
  }
}

Create Employee Template

Path - src/app/create-employee/create-employee.component.html
The create-employee.component.html shows the add employee HTML form. Add the following code to it -
<h3>Create Employee</h3>
<div [hidden]="submitted" style="width: 400px;">
  <form (ngSubmit)="onSubmit()">
    <div class="form-group">
      <label for="name">First Name</label>
      <input type="text" class="form-control" id="firstName" required [(ngModel)]="employee.firstName" name="firstName">
    </div>

    <div class="form-group">
      <label for="name">Last Name</label>
      <input type="text" class="form-control" id="lastName" required [(ngModel)]="employee.lastName" name="lastName">
    </div>

    <div class="form-group">
      <label for="name">Email Id</label>
      <input type="text" class="form-control" id="emailId" required [(ngModel)]="employee.emailId" name="emailId">
    </div>

    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</div>

<div [hidden]="!submitted">
  <h4>You submitted successfully!</h4>
  <!-- <button class="btn btn-success" (click)="newEmployee()">Add</button> -->
</div>

4. Update Employee Template and Component

Let's create update employee component with following Angular CLI command:
> ng g c update-employee

Update Employee Component

Path - src/app/update-employee/update-employee.component.ts
UpdateEmployeeComponent is used to update an existing employee. In this UpdateEmployeeComponent, we first get the employee object using REST API and populate in HTML form via data binding. Users can edit the employee form data and submit the form. 
Let's add the following code to UpdateEmployeeComponent -
import { Component, OnInit } from '@angular/core';
import { Employee } from '../employee';
import { ActivatedRoute, Router } from '@angular/router';
import { EmployeeService } from '../employee.service';

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

  id: number;
  employee: Employee;

  constructor(private route: ActivatedRoute,private router: Router,
    private employeeService: EmployeeService) { }

  ngOnInit() {
    this.employee = new Employee();

    this.id = this.route.snapshot.params['id'];
    
    this.employeeService.getEmployee(this.id)
      .subscribe(data => {
        console.log(data)
        this.employee = data;
      }, error => console.log(error));
  }

  updateEmployee() {
    this.employeeService.updateEmployee(this.id, this.employee)
      .subscribe(data => {
        console.log(data);
        this.employee = new Employee();
        this.gotoList();
      }, error => console.log(error));
  }

  onSubmit() {
    this.updateEmployee();    
  }

  gotoList() {
    this.router.navigate(['/employees']);
  }
}

Update Employee Template

Path - src/app/update-employee/update-employee.component.html The update-employee.component.html shows the update employee HTML form. Add the following code to this file -
<h3>Update Employee</h3>
<div [hidden]="submitted" style="width: 400px;">
  <form (ngSubmit)="onSubmit()">
    <div class="form-group">
      <label for="name">First Name</label>
      <input type="text" class="form-control" id="firstName" required [(ngModel)]="employee.firstName" name="firstName">
    </div>

    <div class="form-group">
      <label for="name">Last Name</label>
      <input type="text" class="form-control" id="lastName" required [(ngModel)]="employee.lastName" name="lastName">
    </div>

    <div class="form-group">
      <label for="name">Email Id</label>
      <input type="text" class="form-control" id="emailId" required [(ngModel)]="employee.emailId" name="emailId">
    </div>

    <button type="submit" class="btn btn-success">Submit</button>
  </form>
</div>

5. Create View Employee Details Template and Component

Here we create view employee details functionality. Let's create an HTML template and component of Employee details functionality.

Employee Details Component

Path - src/app/employee-details/employee-details.component.ts
The EmployeeDetailsComponent component used to display a particular employee detail. Add the following code to it -
import { Employee } from '../employee';
import { Component, OnInit, Input } from '@angular/core';
import { EmployeeService } from '../employee.service';
import { EmployeeListComponent } from '../employee-list/employee-list.component';
import { Router, ActivatedRoute } from '@angular/router';

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

  id: number;
  employee: Employee;

  constructor(private route: ActivatedRoute,private router: Router,
    private employeeService: EmployeeService) { }

  ngOnInit() {
    this.employee = new Employee();

    this.id = this.route.snapshot.params['id'];
    
    this.employeeService.getEmployee(this.id)
      .subscribe(data => {
        console.log(data)
        this.employee = data;
      }, error => console.log(error));
  }

  list(){
    this.router.navigate(['employees']);
  }
}

Employee Details Component Template

Path - src/app/employee-details/employee-details.component.html
The employee-details.component.html displays a particular employee detail. Add the following code to it -
<h2>Employee Details</h2> 

<hr/>
<div *ngIf="employee">
  <div>
    <label><b>First Name: </b></label> {{employee.firstName}}
  </div>
  <div>
    <label><b>Last Name: </b></label> {{employee.lastName}}
  </div>
  <div>
    <label><b>Email Id: </b></label> {{employee.emailId}}
  </div>  
</div>

<br>
<br>
<button (click)="list()" class="btn btn-primary">Back to Employee List</button><br>

6. Employee Service

Path - src/app/employee.service.ts
The EmployeeService will be used to get the data from the backend by calling spring boot APIs. Update the employee.service.ts file inside src/app directory with the following code to it -
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

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

  private baseUrl = 'http://localhost:8080/springboot-crud-rest/api/v1/employees';

  constructor(private http: HttpClient) { }

  getEmployee(id: number): Observable<any> {
    return this.http.get(`${this.baseUrl}/${id}`);
  }

  createEmployee(employee: Object): Observable<Object> {
    return this.http.post(`${this.baseUrl}`, employee);
  }

  updateEmployee(id: number, value: any): Observable<Object> {
    return this.http.put(`${this.baseUrl}/${id}`, value);
  }

  deleteEmployee(id: number): Observable<any> {
    return this.http.delete(`${this.baseUrl}/${id}`, { responseType: 'text' });
  }

  getEmployeesList(): Observable<any> {
    return this.http.get(`${this.baseUrl}`);
  }
}
This completed the development of CRUD operations using Angular 9.
In the next part 4, we will implement the following steps:
  • npm package.json - Configure Dependencies
  • App Routing Module
  • App Component
  • App Component Template
  • App Module
  • Main Index Html File
  • Main (Bootstrap) File
  • Polyfills
  • TypeScript tsconfig.json

Comments

  1. Hi Ramesh. Thanks for uploading this tutorial. I am beginner to Angular.
    I have a question, like when do we subscribe the Observable and when not?

    when fetching employee list ,
    in Employee service there is

    getEmployeesList(): Observable {
    return this.http.get(`${this.baseUrl}`);
    }

    where as in EmployeeListComponent we have

    reloadData() {
    this.employees = this.employeeService.getEmployeesList();
    }

    here we are not using subscribe.

    but while trying to fetch employee details, in service we have

    getEmployee(id: number): Observable {
    return this.http.get(`${this.baseUrl}/${id}`);
    }

    and while calling this method in EmployeeDetails Component

    ngOnInit() {
    this.employee = new Employee();

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

    this.employeeService.getEmployee(this.id)
    .subscribe(data => {
    console.log(data)
    this.employee = data;
    }, error => console.log(error));
    }

    here we are using subscribe. can you please let me know in which situation do we need to subscribe the Observables? Plz help

    ReplyDelete

Post a Comment

Leave Comment