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

In the previous Part 2, we have installed and created Angular 8 web application. In this Part 3 of Spring Boot + Angular 7 CRUD Example Tutorial, we will develop CRUD operations for an employee model using Angular 8.

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

Table of contents

  • Create an Employee class
  • Employee Service
  • Creating Employee List Template and Component
  • Create Add Employee Template and Component
  • Create View Employee Details Template and Component

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;
}

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 employee, 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>

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 it -
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), error => console.log(error));
    this.employee = new Employee();
    this.gotoList();
  }

  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">First Name</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>

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 display a particular employee detail. Add 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>

Employee Service

Path - src/app/employee.service.ts
The EmployeeService will be used to get the data from 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}`);
  }
}
Note that update employee functionality is not implemented so you can take as exercise and try to implement yourself (Tip 1: Add an update button to the employee list page and based on employee id you can implement update functionality. Note that Rest API is already created for update employee functionality. Tip 2: Refer to employee details functionality to get employee id from one component to another component (Update Employee Component) ).

This completed the development of CRUD operations using Angular 8.
In the next Part 4, we will learn the following topics:
  • 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