Tutorial: “Angular SpringBoot CRUD MySQL Example”
In the tutorial, I introduce how to create an “SpringBoot Angular MySQL CRUD Example” with POST/GET/PUT/DELETE requests to SpringBoot RestAPIs.
– Design overview system by Architecture Diagram that includes: Angular Client, SpringBoot RestAPIs, and MySQL database.
– Implement Angular CRUD Client with Angular built-in HttpClient to communicate with server side.
– Implement SpringBoot RestAPIs that gets data from MySQL using Spring Data JPA and returns back data as Json format to requested Angular Client.
You can check out the complete code of the application on this github repository.
- Overall Angular SpringBoot MySQL CRUD Architecture Application
- Overview SpringBoot CRUD MySQL Backend Architecture
- Overview Angular CRUD Architecture Design
- Goal – Angular SpringBoot CRUD MySQL
- Video Guide – Angular SpringBoot CRUD MySQL Example FullStack DEBUG
- Create SpringBoot Application
- SpringBoot CRUD MySQL/PostgreSQL Database Configuration
- SpringBoot Define Spring JPA Data Model
- SpringBoot Implement JPA Repository and Service
- SpringBoot Implement RestAPIs Controller – POST/GET/PUT/DELETE
- SpringBoot CRUD RestAPI: Add New Customer Controller
- SpringBoot CRUD RestAPI Get a Customer by ID Controller
- SpringBoot CRUD RestAPI Get All Customers Controller
- SpringBoot CRUD RestAPI Delete a Customer Controller
- SpringBoot CRUD RestAPI Update a Customer Controller
- SpringBoot CRUD MySQL/PostgreSQL RestAPI Backend Testing
- Angular SpringBoot CRUD MySQL Application Overview
- Create Angular CRUD Application
- Angular Create Data Model
- Angular Create Message Model
- Angular Implement Angular HttpClient Customer Service
- Angular HttpClient POST Request – Add new Customer
- Angular HttpClient GET Request – Retrieve Customers
- Angular HttpClient PUT Request – Modify a Customer
- Angular HttpClient DELETE Request – Delete a Customer
- Angular Implement Message Service
- Angular Implement Component: Add Customer
- Angular Implement add-customer.component.ts
- Angular Implement add-customer.component.html view
- Angular Implement Component: List Customers
- Angular Implement list-customers.component.ts
- Angular Implement list-customers.component.html
- Angular Implement Component: Message Component
- Angular Configure App Routing Module
- Modify Angular index.html view page
- Angular CRUD Application Testing
- Sourcecode – Angular SpringBoot CRUD MySQL Example
Overall Angular SpringBoot MySQL CRUD Architecture Application

- We build backend SpringBoot Application that provides RestAPIs for POST/GET/PUT/DELETE Customer entities and store them in MySQL/PostgreSQL database.
- We implement Angular Application that use Angular HTTPClient to interact (call/receive requests) with SpringBoot backend and display corresponding page view in browser.
Overview SpringBoot CRUD MySQL Backend Architecture

- For building RestAPIs in SpringBoot application, we use Spring MVC Web.
- For interacting with database MySQL/PostgreSQL, we use Spring JPA.
- We implement RestAPI’s URL in RestAPIController.java file to process bussiness logic.
- For manipulating database’s records, we define a JPA model for mapping field data and use a JPA CRUD repository to do CRUD operation with MySQL/PostgreSQL.
– SpringBoot Project Structure

models
package definesCustomer
model andMessage
response class.repository
package defines Spring JPA repository classCustomerRepository
to do CRUD operation with database.service
package defines a middleware classCustomerServices
between Controller and Repository.controller
package defines a RestAPI ControllerRestAPIController
to handle POST/GET/PUT/DELETE request.
Overview Angular CRUD Architecture Design

Angular CRUD Application is designed with 3 main layers:
- Service Layer is used to define Angular Common Services and HttpClient Services to interact with RestAPIs
- Component Layer is used to define Angular Components to show views in Browser for interacting with Users
- Router Layer is used to route URLs mapping with the corresponding Angular Components
Angular Project Structure:

Angular CRUD Application defines 3 components, 2 services, 1 routers, and 2 data models:
– Components:
add-customer
component is used to add a new customer to systemlist-customer
component is used to show all customers on view pages, delete a customer and update a customermessage
component is used to define a view to show logging message on browser
– Services:
customer.service.ts
defines POST/GET/PUT/DELETE HTTP requests to SpringBoot RestAPIs with the built-in Angular HttpClient.message.service.ts
defines an array storage to log all messages when Angular CRUD App running
– Router: app-routing.module.ts
defines how to map a corresponding Angular component with an URL.
– Models:
customer.ts
defines the main data model of our application.message.ts
defines the response data model between SpringBoot and Angular application.
Goal – Angular SpringBoot CRUD MySQL
– Add new Customer: from Angular to SpringBoot and save to MySQL.

– List All Customers: from Angular calls SpringBoot RestAPI to get customer from MySQL.

– Details a Customer: from Angular calls get http request from SpringBoot RestAPI to get a record in MySQL database

– Update a Customer: from Angular calls a put http request from SpringBoot RestAPI to update a record in MySQL database.

– Delete a Customer: from Angular calls a delete http request from SpringBoot RestAPI to delete a record in MySQL database.

– Check database records: do a get request from Angular to SpringBoot RestAPI.

Video Guide – Angular SpringBoot CRUD MySQL Example FullStack DEBUG
Create SpringBoot Application
For building SpringBoot RestAPIs CRUD Application, we need Spring Web, Spring JPA and MySQL or PostgreSQL driver, so we add below dependencies in pom.xml
file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
– If you use PostgreSQL database, we add below driver dependency:
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
SpringBoot CRUD MySQL/PostgreSQL Database Configuration
– With MySQL, We add below database configuration in application.properties
:
spring.datasource.url=jdbc:mysql://localhost:3306/loizenaidb
spring.datasource.username=root
spring.datasource.password=12345
spring.jpa.generate-ddl=true
#drop & create table again, good for testing, comment this in production
spring.jpa.hibernate.ddl-auto=create
– With PostgreSQL, we add below database configuration in application.properties
:
## PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/loizenaidb
spring.datasource.username=postgres
spring.datasource.password=123
#drop & create table again, good for testing, comment this in production
spring.jpa.hibernate.ddl-auto=create
SpringBoot Define Spring JPA Data Model
We create a Customer
model class with 5 attributes:
- id
- firstname
- lastname
- address
- age
– Coding:
package com.example.loizenai.crudapp.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* @Copyright by https://loizenai.com
* @author https://loizenai.com
* youtube loizenai
*/
@Entity
@Table(name="customer")
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@Column
private String firstname;
@Column
private String lastname;
@Column
private String address;
@Column
private int age;
public void setId(long id) {
this.id = id;
}
public long getId() {
return this.id;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getFirstname() {
return this.firstname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getLastname() {
return this.lastname;
}
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return this.address;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
protected Customer() {}
public Customer(String firstname, String lastname, String address, int age) {
this.firstname = firstname;
this.lastname = lastname;
this.address = address;
this.age = age;
}
public String toString() {
return String.format("id=%d, firstname='%s', lastname'%s', address=%s, age=%d",
id, firstname, lastname, address, age);
}
}
– @Column
specifies the mapped column for a persistent property or field. If no Column annotation is specified, the default values apply.
– javax.persistence.Id
specifies the primary key of an entity.
– javax.persistence.Entity
specifies that the class is an entity. This annotation is applied to the entity class.
SpringBoot Implement JPA Repository and Service
For doing CRUD operations with database, we define an interface CustomerRepository
that extends class JpaRepository
:
@Repository
public interface CustomerRepository extends JpaRepository{
}
– We implement a middleware class service CustomerServices
between CustomerRepository
and RestAPIController
:
package com.example.loizenai.crudapp.service;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.example.loizenai.crudapp.model.Customer;
import com.example.loizenai.crudapp.repository.CustomerRepository;
/**
* @Copyright by https://loizenai.com
* @author https://loizenai.com
* youtube loizenai
*/
@Service
public class CustomerServices {
@Autowired CustomerRepository repository;
public Customer saveCustomer(Customer customer) {
return repository.save(customer);
}
public List<Customer> getCustomerInfos(){
return repository.findAll();
}
public Optional<Customer> getCustomerById(long id) {
return repository.findById(id);
}
public boolean checkExistedCustomer(long id) {
if(repository.existsById((long) id)) {
return true;
}
return false;
}
public Customer updateCustomer(Customer customer) {
return repository.save(customer);
}
public void deleteCustomerById(long id) {
repository.deleteById(id);
}
}
SpringBoot Implement RestAPIs Controller – POST/GET/PUT/DELETE
We implement a RestAPI Controller RestAPIController
to handle POST/GET/PUT/DELETE request-mapping with 5 APIs:
addNewCustomer(@RequestBody Customer customer)
handles POST request to add a new customer.ResponseEntity retrieveCustomerInfo()
handles GET request to retrieve all customers.getCustomerById(@PathVariable long id)
handles GET request to get a customer by given id.updateCustomerById(@RequestBody Customer _customer, @PathVariable long id)
handles PUT request to update a customerdeleteCustomerById(@PathVariable long id)
handles DELETE request to delete a Customer from database

@RestController
@RequestMapping("/api/customer")
public class RestAPIController {
@Autowired
CustomerServices customerServices;
...
}
SpringBoot CRUD RestAPI: Add New Customer Controller
@PostMapping("/create")
public ResponseEntity<Message> addNewCustomer(@RequestBody Customer customer) {
try {
Customer returnedCustomer = customerServices.saveCustomer(customer);
return new ResponseEntity<Message>(new Message("Upload Successfully!",
Arrays.asList(returnedCustomer), ""), HttpStatus.OK);
}catch(Exception e) {
return new ResponseEntity<Message>(new Message("Fail to post a new Customer!",
null, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
SpringBoot CRUD RestAPI Get a Customer by ID Controller
@GetMapping("/findone/{id}")
public ResponseEntity<Message> getCustomerById(@PathVariable long id) {
try {
Optional<Customer> optCustomer = customerServices.getCustomerById(id);
if(optCustomer.isPresent()) {
return new ResponseEntity<Message>(new Message("Successfully! Retrieve a customer by id = " + id,
Arrays.asList(optCustomer.get()), ""), HttpStatus.OK);
} else {
return new ResponseEntity<Message>(new Message("Failure -> NOT Found a customer by id = " + id,
null, ""), HttpStatus.NOT_FOUND);
}
}catch(Exception e) {
return new ResponseEntity<Message>(new Message("Failure",
null, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
SpringBoot CRUD RestAPI Get All Customers Controller
@GetMapping("/retrieveinfos")
public ResponseEntity<Message> retrieveCustomerInfo() {
try {
List<Customer> customerInfos = customerServices.getCustomerInfos();
return new ResponseEntity<Message>(new Message("Get Customers' Infos!",
customerInfos, ""), HttpStatus.OK);
}catch(Exception e) {
return new ResponseEntity<Message>(new Message("Fail!",
null, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
SpringBoot CRUD RestAPI Delete a Customer Controller
@DeleteMapping("/deletebyid/{id}")
public ResponseEntity<Message> deleteCustomerById(@PathVariable long id) {
try {
// checking the existed of a Customer with id
if(customerServices.checkExistedCustomer(id)) {
customerServices.deleteCustomerById(id);
return new ResponseEntity<Message> (new Message("Successfully! Delete a Customer with id = " + id,
null, ""), HttpStatus.OK);
}else {
return new ResponseEntity<Message>(new Message("Failer! Can NOT Found a Customer "
+ "with id = " + id, null, ""), HttpStatus.NOT_FOUND);
}
}catch(Exception e) {
return new ResponseEntity<Message>(new Message("Failure",
null, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
SpringBoot CRUD RestAPI Update a Customer Controller
@PutMapping("/updatebyid/{id}")
public ResponseEntity<Message> updateCustomerById(@RequestBody Customer _customer,
@PathVariable long id) {
try {
if(customerServices.checkExistedCustomer(id)) {
Customer customer = customerServices.getCustomerById(id).get();
//set new values for customer
customer.setFirstname(_customer.getFirstname());
customer.setLastname(_customer.getLastname());
customer.setAddress(_customer.getAddress());
customer.setAge(_customer.getAge());
// save the change to database
customerServices.updateCustomer(customer);
return new ResponseEntity<Message>(new Message("Successfully! Updated a Customer "
+ "with id = " + id,
Arrays.asList(customer), ""), HttpStatus.OK);
}else {
return new ResponseEntity<Message>(new Message("Failer! Can NOT Found a Customer "
+ "with id = " + id,
null, ""), HttpStatus.NOT_FOUND);
}
}catch(Exception e) {
return new ResponseEntity<Message>(new Message("Failure",
null, e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
SpringBoot CRUD MySQL/PostgreSQL RestAPI Backend Testing
For testing sourcecode with Postman RestClient, need comment out the line of code:
@CrossOrigin(origins = "http://localhost:4200")
in RestAPIController
file.
Testcase 1 – Add new Customer:
– Post a new customer:

– Check database records:

Testcase 2 – Get a Customer by Id
– Get a Customer with id = 4:

Testcase 3 – Get All Customers
– Retrieve all customers:

Testcase 4 – Delete a Customer by Id
– Delete a Customer with id = 2:

Testcase 5 – Update a Customer
– Update a Customer with id = 3:

Angular SpringBoot CRUD MySQL Application Overview

– For more details, we go back to the session: Angular CRUD Design
Create Angular CRUD Application
We create Angular CRUD project by commandline: ng new AngularHttpclient
.
– Create 3 components AddCustomer
, ListCustomers
, Message
by cmd:
ng g component AddCustomer
ng g component ListCustomers
ng g component Message
– Create 2 Angular services CustomerService
, MessageService
by cmd:
ng g service customer
ng g service message
– Create 2 models Customer
and Message
by cmd:
ng g class customer;
ng g class message;
Angular Create Data Model
We define Customer
class with 5 attributes:
export class Customer {
id: number;
firstname: string;
lastname: string;
age: number;
address: string
}
Angular Create Message Model
We define Message
class as below:
import { Customer } from './customer';
export class Message {
message: string;
error: string;
customers: Customer[];
}
Angular Implement Angular HttpClient Customer Service
For interacting with Backend RestAPIs, we use Angular built-in Httpclient service:
@Injectable({
providedIn: 'root'
})
export class CustomerService {
private baseUrl = 'http://localhost:8080/api/customers';
constructor(private http: HttpClient) { }
...
To handle Error, we implement a function private handleError(error: HttpErrorResponse)
:
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error('An error occurred:', error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(
`Backend returned code ${error.status}, ` +
`body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError(
'Something bad happened; please try again later.');
};
Angular HttpClient POST Request – Add new Customer
createCustomer(customer: Customer): Observable<Message> {
return this.http.post<Message>(`${this.baseUrl}` + `/create`, customer)
.pipe(
retry(3),
catchError(this.handleError)
);
}
– The above function posts a Customer to SpringBoot backend server at URL http://localhost:8080/api/customers/create
– retry(3)
is used to retry a failed request up to 3 times
Angular HttpClient GET Request – Retrieve Customers
– Retrieve all Customers from SpringBoot backend at RestAPI by a GET request at URL http://localhost:8080/api/customers/retrieveinfos
.
retrieveAllCustomers(): Observable {
return this.http.get(`${this.baseUrl}` + `/retrieveinfos`)
.pipe(
retry(3),
catchError(this.handleError)
);
}
Angular HttpClient PUT Request – Modify a Customer
– Update a Customer with Angular Httpclient by a PUT request at URL:
http://localhost:8080/api/customers/updatebyid/{id}
updateCustomer(customer: Customer): Observable<Message> {
return this.http.put<Message> (`${this.baseUrl}` + `/updatebyid/` + customer.id, customer)
.pipe(
retry(3),
catchError(this.handleError)
);
}
Angular HttpClient DELETE Request – Delete a Customer
– Delete a Customer by a given id with Angular Httpclient by a DELETE request at URL:
http://localhost:8080/api/customers/deletebyid/{id}
:
deleteCustomer(id: number): Observable<Message> {
return this.http.delete<Message>(`${this.baseUrl}` + `/deletebyid/` + id)
.pipe(
retry(3),
catchError(this.handleError)
);
}
Angular Implement Message Service
For tracking the proccessing of each proccessing in Angular CRUD Application, We implement a Message service to store tracing-logs message then display them on Html.
The message.service.ts
has an string array messages
to store tracing-log messages and 2 functions: add(message: string)
and clear()
– Coding:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class MessageService {
messages: string[] = [];
add(message: string) {
this.messages.push(message);
}
clear(){
this.messages = [];
}
}
Angular Implement Component: Add Customer
AddCustomerComponent
is used to post a new Customer to SpringBoot backend server.
– We have 2 parts:
add-customer.component.ts
fileadd-cusomer.component.html
file
Angular Implement add-customer.component.ts
import { Component, OnInit } from '@angular/core';
import { Customer } from '../customer';
import { CustomerService } from '../customer.service';
import { Message } from '../message';
import { MessageService } from '../message.service';
@Component({
selector: 'app-add-customer',
templateUrl: './add-customer.component.html'
})
export class AddCustomerComponent implements OnInit {
customer: Customer;
/**
* Constructing Http Customer Service
* @param customerService
*/
constructor(private customerService: CustomerService,
private messageService: MessageService) { }
ngOnInit(): void {
this.customer = new Customer();
}
/**
* Store a Customer to backend server
*/
save() {
this.customerService.createCustomer(this.customer)
.subscribe((message: Message) => {
console.log(message);
let customer = message.customers[0];
let msg = "Success -> Post a Customer: "
+ "<ul>"
+ "<li>id: " + customer.id + "</li>"
+ "<li>firstname: " + customer.firstname + "</li>"
+ "<li>lastname: " + customer.lastname + "</li>"
+ "<li>age: " + customer.age + "</li>"
+ "<li>address: " + customer.address + "</li>"
+ "</ul>";
this.messageService.add(msg);
}, error => {
console.log(error);
let msg = "Error! -> Action Posting a Customer:"
+ "<ul>"
+ "<li>id = " + this.customer.id + "</li>"
+ "<li>firstname = " + this.customer.firstname + "</li>"
+ "<li>lastname = " + this.customer.lastname + "</li>"
+ "<li>age = " + this.customer.age + "</li>"
+ "<li>address = " + this.customer.address + "</li>"
+ "</ul>";
this.messageService.add(msg);
});
}
reset(){
this.customer = new Customer();
}
/**
* Function handles form submitting
*/
onSubmit() {
this.save();
this.reset();
}
}
Angular Implement add-customer.component.html view
<h2>Create Customer</h2>
<div>
<form (ngSubmit)="onSubmit()">
<!-- First name -->
<div class="form-group">
<label for="firstname">First Name:</label>
<input type="text" class="form-control" placeholder="Enter Firstname"
id="firstname" required [(ngModel)]="customer.firstname" name="firstname">
</div>
<!-- Last name -->
<div class="form-group">
<label for="lastname">Last Name:</label>
<input type="text" class="form-control" placeholder="Enter Lastname"
id="lastname" required [(ngModel)]="customer.lastname" name="lastname">
</div>
<!-- Address -->
<div class="form-group">
<label for="address">Address:</label>
<input type="text" class="form-control" placeholder="Enter Address"
id="address" required [(ngModel)]="customer.address" name="address">
</div>
<!-- Age -->
<div class="form-group">
<label for="age">Age</label>
<input type="number" class="form-control" placeholder="Enter Age"
id="age" required [(ngModel)]="customer.age" name="age">
</div>
<button type="submit" class="btn btn-success">Submit</button>
</form>
</div>
<app-message></app-message>
Angular Implement Component: List Customers
ListCustomersComponent
has 4 main functions:
- Show all Customers
- Show details a Customers
- Delete a Customer
- Update a Customer
Angular Implement list-customers.component.ts
import { Component, OnInit } from '@angular/core';
import { Customer } from '../customer';
import { MessageService } from '../message.service';
import { CustomerService } from '../customer.service';
import { Message } from '../message';
@Component({
selector: 'app-list-customers',
templateUrl: './list-customers.component.html'
})
export class ListCustomersComponent implements OnInit {
customers: Array<Customer> = [];
showCustomer: Customer;
isSelected: boolean = false;
deletedCustomer: Customer;
returnedMessage: string;
constructor(private customerService: CustomerService,
private messageService: MessageService) { }
setCustomerDetails(customer: Customer){
this.isSelected=!this.isSelected;
if(this.isSelected){
this.showCustomer = customer;
}else{
this.showCustomer = undefined;
}
}
/**
* Set deletedCustomer and reset returnedMessage = undefined
* @param deleteCustomer
*/
prepareDeleteCustomer(deleteCustomer: Customer){
//assign delete-Customer
this.deletedCustomer = deleteCustomer;
// reset returned-Message
this.returnedMessage = undefined;
}
/**
* Delete a Customer by ID
*/
deleteCustomer(){
console.log("--- Access delelteCustomer() function");
this.customerService.deleteCustomer(this.deletedCustomer.id)
.subscribe((message: Message) => {
console.log(message);
// remove a deletedCustomer from customers list on view
this.customers = this.customers.filter(customer => {
return customer.id != this.deletedCustomer.id;
})
// set a showing message in delete modal
this.returnedMessage = message.message;
// just reset showCustomer for not showing on view
this.showCustomer = undefined;
// add the delete message to message app for showing
this.messageService.add(message.message);
},
(error) => {
console.log(error);
let errMsg: string = "Error! Details: " + error;
this.messageService.add(errMsg);
});
}
/**
* Update Customer function
*/
updateCustomer() {
this.customerService.updateCustomer(this.showCustomer)
.subscribe((message: Message) => {
console.log(message);
// update customers list
this.customers.map(x => {
if(x.id == this.showCustomer.id){
x = this.showCustomer;
}
});
let msg: string = "Update Successfully! -> New Customer's properties: <br>"
+ "<ul>"
+ "<li>" + "id: " + this.showCustomer.id + "</li>"
+ "<li>" + "firstname: " + this.showCustomer.firstname + "</li>"
+ "<li>" + "lastname: " + this.showCustomer.lastname + "</li>"
+ "<li>" + "age: " + this.showCustomer.age + "</li>"
+ "<li>" + "address: " + this.showCustomer.address + "</li>"
+ "</ul>";
this.messageService.add(msg);
}
, (error) => {
console.log(error);
let errMsg = "Update Fail ! Error = " + error;
this.messageService.add(errMsg);
});
}
/**
* Retrieve all Customer from Backend
*/
retrieveAllCustomers() {
this.customerService.retrieveAllCustomers()
.subscribe((message: Message) => {
console.log(message);
this.customers = message.customers;
}
, (error) => {
console.log(error);
});
}
ngOnInit(): void {
this.retrieveAllCustomers();
}
}
Angular Implement list-customers.component.html
<div *ngIf="customers.length">
<h3>Customers</h3>
<br>
<table class="table table-hover table-sm">
<thead class="thead-dark">
<tr>
<th>Id</th>
<th>Firstname</th>
<th>Address</th>
<th></th>
</tr>
</thead>
<tbody>
<tr *ngFor="let customer of customers">
<td>
<button type="button" class="btn btn-primary" (click)="setCustomerDetails(customer)">
{{customer.id}}
</button>
</td>
<td>{{customer.firstname}}</td>
<td>{{customer.address}}</td>
<td>
<button type="button" class="btn btn-danger"
data-toggle="modal" data-target="#delete-modal"
(click)=prepareDeleteCustomer(customer) >×</button>
</td>
</tr>
</tbody>
</table>
</div>
<!-- The Modal -->
<div class="modal fade" id="delete-modal">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header">
<h4 class="modal-title">Delete!</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Modal body -->
<div class="modal-body">
<div *ngIf="deletedCustomer">
<p [hidden] = "returnedMessage">
Do you want delete a customer with id = {{deletedCustomer.id}}
</p>
<p [hidden] = "!returnedMessage">
{{returnedMessage}}
</p>
</div>
</div>
<!-- Modal footer -->
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button [hidden] = "returnedMessage" type="button" class="btn btn-danger" (click)="deleteCustomer()">Delete</button>
</div>
</div>
</div>
</div>
<div *ngIf="showCustomer">
<h3>Update Customer</h3>
<form (ngSubmit)="updateCustomer()">
<!-- ID -->
<div class="form-group">
<label for="id">Id:</label>
<input type="numer" class="form-control"
id="id" required [(ngModel)]="showCustomer.id" name="id" disabled>
</div>
<!-- First name -->
<div class="form-group">
<label for="firstname">First Name:</label>
<input type="text" class="form-control" placeholder="Enter Firstname"
id="firstname" required [(ngModel)]="showCustomer.firstname" name="firstname">
</div>
<!-- Last name -->
<div class="form-group">
<label for="lastname">Last Name:</label>
<input type="text" class="form-control" placeholder="Enter Lastname"
id="lastname" required [(ngModel)]="showCustomer.lastname" name="lastname">
</div>
<!-- Address -->
<div class="form-group">
<label for="address">Address:</label>
<input type="text" class="form-control" placeholder="Enter Address"
id="address" required [(ngModel)]="showCustomer.address" name="address">
</div>
<!-- Age -->
<div class="form-group">
<label for="age">Age</label>
<input type="number" class="form-control" placeholder="Enter Age"
id="age" required [(ngModel)]="showCustomer.age" name="age">
</div>
<button type="submit" class="btn btn-success">Update</button>
</form>
</div>
<app-message></app-message>
<script>
let pathname = window.location.pathname;
if(pathname == ""){
$(".nav .nav-item a:first").addClass("active");
$(".nav .nav-item a:last").removeClass("active");
} else if (pathname == "/customers") {
$(".nav .nav-item a:last").addClass("active");
$(".nav .nav-item a:first").removeClass("active");
}
alert("ok");
</script>
Angular Implement Component: Message Component
MessageComponent
is used to show all tracing-log messages in html view.
– Implement message.component.ts:
import { Component, OnInit } from '@angular/core';
import { MessageService } from '../message.service';
@Component({
selector: 'app-message',
templateUrl: './message.component.html'
})
export class MessageComponent {
constructor(public messageService: MessageService) {}
}
– Implement message.component.html:
<div *ngIf="messageService.messages.length">
<h3>Messages</h3>
<button type="button" class="btn btn-secondary" (click)="messageService.clear()">clear</button>
<br>
<ol>
<li *ngFor='let message of messageService.messages'>
<div [innerHTML]="message">
</div>
</li>
</ol>
</div>
Angular Configure App Routing Module
To handle the navigation from one view to the next, you use the Angular router. The router enables navigation by interpreting a browser URL as an instruction to change the view.
The following command uses the Angular CLI to generate a basic Angular app with an app routing module, called AppRoutingModule
, which is an NgModule where you can configure your routes.
ng new routing-app --routing
How to Define a route? -> There are three fundamental building blocks to creating a route.
1. Import the AppRoutingModule into AppModule and add it to the imports array.
The Angular CLI performs this step for you. However, if you are creating an app manually or working with an existing, non-CLI app, verify that the imports and configuration are correct.
import { AppRoutingModule } from './app-routing.module';
...
@NgModule({
declarations: [
...
],
imports: [
...
AppRoutingModule,
...
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
2. Define your routes in your Routes array
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AddCustomerComponent } from './add-customer/add-customer.component';
import { ListCustomersComponent } from './list-customers/list-customers.component';
const routes: Routes = [
{
path: '',
component: AddCustomerComponent
},
{
path: 'customers',
component: ListCustomersComponent
}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
3. Add your routes to your application.
In the index.html
file, we add below html code for navigating URL:
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<ul class="navbar-nav">
<li class="nav-item" id="li_add_customer">
<a class="nav-link" href="">Add Customer</a>
</li>
<li class="nav-item" id="li_list_customers">
<a class="nav-link" href="/customers">List Customers</a>
</li>
</ul>
</nav>
Next, update your component template to include app.component.ts
file, add the tag:
<router-outlet></router-outlet>
Modify Angular index.html view page
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>AngularHttpclient</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
<!-- jQuery library -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Popper JS -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
<!-- Latest compiled JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
</head>
<body>
<div class="container" >
<div class="col-sm-5" style="background-color: #ffffcc; margin:10px;padding:10px; border-radius: 5px">
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
<ul class="navbar-nav">
<li class="nav-item" id="li_add_customer">
<a class="nav-link" href="">Add Customer</a>
</li>
<li class="nav-item" id="li_list_customers">
<a class="nav-link" href="/customers">List Customers</a>
</li>
</ul>
</nav>
<app-root></app-root>
</div>
</div>
<script>
$(document).ready(function() {
(function(){
let pathname = window.location.pathname;
if(pathname == "/"){
$("#li_add_customer").addClass("active");
$("#li_list_customers").removeClass("active");
} else if (pathname == "/customers") {
$("#li_list_customers").addClass("active");
$("#li_add_customer").removeClass("active");
}
})();
});
</script>
</body>
</html>
Angular CRUD Application Testing
– Testcase 1 – Add New Customer:


– Testcase 2 – Retrieve All Customers


– Testcase 3 – Update a Customer:


– Testcase 4 – Delete a Customer:


Sourcecode – Angular SpringBoot CRUD MySQL Example
Below are all sourcecodes (includes github) for the tutorial: “SpringBoot + Angular CRUD Example with MySQL” :
– SpringBoot backend’s sourcecode with below implemented features:
– GitHub Sourcecode for SpringBoot Angular CRUD Example:
SpringBoot-CRUD-MySQL-Application – GitHub Sourcecode
– Angular CRUD Application Sourcecode with below implemented features:
– GitHub Sourcecode
Angular Crud MySQL Example Application – GitHub
So best