In the tutorial, I introduce how to build an “Angular 8 SpringBoot MongoDB CRUD Example RestAPIs” project with the help of SpringData and Atlas MongoDB for POST/GET/PUT/DELETE requests with step by step coding examples:
– SpringBoot project produces CRUD RestAPIs with MongoDB database documents using the supporting of Spring Data.
– Angular 8 project will consume the SpringBoot CRUD RestAPIs then show up on component’s views.
– I draw a fullstack overview Diagram Architecture from Angular 8 Frontend to MongoDB database through SpringBoot RestAPI backend.
– Develop SpringBoot CRUD RestAPIs with the supporting of SpringWeb Framework.
– Implement Angular 8 CRUD application with the Angular 8 Httpclient to do CRUD request (Post/Get/Put/Delete) to SpringBoot Backend APIs.
– I create a testsuite with a number of integrative testcases with CRUD RestAPI requests from Angular 8 HttpClient to do CRUD requests to SpringBoot RestAPIs Server and save/retrieve data to MongoDB database.
- Overview Example – How to build Angular 8 SpringBoot MongoDB CRUD Example?
- Spring Boot MongoDB CRUD RestAPIs Example – Backend Development
- Angular 8 CRUD Application Example – Frontend Development
- Angular 8 CRUD Application Overview with SpringBoot RestAPIs
- Create Angular 8 Application
- Create Angular 8 Typescript Model
- Create Typescript Message
- Implement Angular 8 CRUD HttpClient Service
- Implement Angular 8 post/get/put/delete components
- Configure Angular 8 Routing Module
- Modify Index.html View Page
- Integrative Testing: Angular 8 Application with SpringBoot CRUD RestAPIs + MongoDB
- Sourcecode
- Further Reading
Overview Example – How to build Angular 8 SpringBoot MongoDB CRUD Example?
Overall Architecture System: Angular 8 + SpringBoot + MongoDB

- We build a backend: SpringBoot CRUD Application with MongoDB Atlas that provides RestAPIs for POST/GET/PUT/DELETE data entities and store them in MongoDB database.
- We implement Angular 8 CRUD Application that use Angular 8 HTTPClient to interact (call/receive requests) with SpringBoot CRUD application and display corresponding data in Angular 8 Component.
SpringBoot MongoDB CRUD Design Application

I build a SpringBoot project that handle all Post/Get/Put/Delete requests from RestClient and do CRUD operations to MongoDB Atlas database to save/retrieve/update and delete documents from MongoDB and returns back to Restclient the corresponding messages.
We build a SpringBoot project with 3 layers:
– MongoDB Repository is used to interact with MongoDB database by a set of CRUD operations.
– Service is the middle-ware layer for interating with RestController layer and MongoDB Repository layer. This is a transforming machine, it gets the needed data from web-requests through RestController and do CRUD operation to MongoDB via MongoDB Repository layer.
– RestController layer is a web layer for SpringBoot project, it will directly handle all incomming requests and do the corressponding responses to the calling client.
Angular 8 HttpClient CRUD Application Design

– Angular 8 CRUD Application is designed with 3 main layers:
- Service Layer is used to define Angular 8 Common Services and Angular 8 HttpClient Services to do CRUD requests with Nodejs RestAPIs
- Component Layer is used to define Angular 8 Components to display views in Browser.
- Router Layer is used to define all Angular 8 navigation URLs mapping with the corresponding Angular 8 Components

Angular 8 CRUD Application defines 3 components, 2 services, 1 routers, and 2 data models:
– Angular 8 Components:
add-customer
component is used to post a new data to MongoDB via Nodejs RestAPIlist-customer
component is used to display all data on views, delete a data and update a data with
a given id to MongoDB using Nodejs RestAPIs: Get/Put/Deletemessage
component is used to define a view to show logging message on browser
– Angular 8 Services:
customer.service.ts
defines CRUD Angular 8 httpclient post/get/put/delete requests to Node.js Express RestAPIsmessage.service.ts
defines an array storage to log all messages when the Angular 10 CRUD App running
– Angular 8 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 Angular 8 application.message.ts
defines the response data model between Nodejs and Angular 8 application.
Project Goal
– Angular 8 adds a data:

– Angular 8 SpringBoot MongoDB list all data:

– Angular update a data:

– Delete a record:

– Check all MongoDB’s documents:

– Check Mongodb documents after doing CRUD requests
Spring Boot MongoDB CRUD RestAPIs Example – Backend Development
Now it’s time for building the “SpringBoot MongoDB CRUD RestAPIs Example” project with a set of simple steps:
- Create SpringBoot project
- Configure MongoDB Database
- Define Spring Data MongoDB’s Document Model
- Define SpringBoot MongoDB Repository
- Implement SpringBoot Customer Service
- Implement SpringBoot MongoDB CRUD RestAPIs
Let’s go!
How to build SpringBoot MongoDB CRUD RestAPI project
Create SpringBoot MongoDB project
We use SpringToolSuite to create a simple SpringBoot project with below structure:

application.properties
is used to add the SpringBoot application’s configurations such as: database configuration (MongoDB, MySQL, PostgreSQL), threadpool, Hibernate, JPA …repository
package is used to define a SpringBoot MongoDB repository to do CRUD operations with MongoDBrest
package is used to implement a SpringBoot RestAPI controller to handle all incomming requests (post/get/put/delete) and response to rest-client.service
package is used to implement a middleware machine between RestAPIs controller and Mongo Repository of SpringBoot project.model
package is used to define the MongoDB document’s schema that maps with the document format in MongoDB database
For handling the web-request and doing CRUD operations with MongoDB database, we need the supporting of 2 SpringBoot dependencies: spring-boot-starter-web
and spring-boot-starter-data-mongodb
. So adding it to pom.xml
file:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
SpringBoot Configure MongoDB Database
To initialize a connection with MongoDB Atlas, we open the file application.properties
and add below uri configure:
#mongodb
spring.data.mongodb.uri=mongodb+srv://loizenjava:loizenjava@cluster0.gmd7e.mongodb.net/loizenjavadb?retryWrites=true&w=majority
Define Spring Data MongoDB’s Document Model
Now we define a Customer class for mapping data between SpringBoot application with MongoDB documents:
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document(collection = "customers")
public class Customer {
@Id
private String id;
private String firstname;
private String lastname;
private Integer age;
private String address;
@Field
private String copyrightby = "https://loizenjava.com";
public Customer(String firstname, String lastname, int age, String address) {
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
this.address = address;
}
// getters and setters
// ...
– @Document
is used to identify a domain object to be persisted to MongoDB.
Here is a sample domain object to be persisted to MongoDB:

Define SpringBoot MongoDB Repository
– Create a CustomerRepository
interface that extends MongoRepository
:
package com.loizenjava.springboot.mongodb.repository;
import org.springframework.data.mongodb.repository.MongoRepository;
import com.loizenjava.springboot.mongodb.model.Customer;
public interface CustomerRepository extends MongoRepository<Customer, String>{
}
With the CustomerRepository
interface, we can do all CRUD operations (save/retrieve/update/delete) from SpringBoot application to MongoDB database.
Implement SpringBoot Customer Service
Now we implement a middle service between RestController layer and MongoDB Repository, by creating a file CustomerService
that uses mongodb repository CustomerRepository
as below code:
package com.loizenjava.springboot.mongodb.service;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.loizenjava.springboot.mongodb.exception.CustomException;
import com.loizenjava.springboot.mongodb.model.Customer;
import com.loizenjava.springboot.mongodb.repository.CustomerRepository;
@Service
public class CustomerService {
@Autowired
CustomerRepository repo;
public Customer saveCustomer(Customer customer){
return repo.save(customer);
}
public List<Customer> retrieveAllCustomers(){
return repo.findAll();
}
public Customer updateCustomer(String id, Customer customer) throws CustomException {
Optional<Customer> customerOpt = repo.findById(id);
if(!customerOpt.isPresent()) {
throw new CustomException("404", "Can not find a customer for updating with id = " + id);
}
Customer _customer = customerOpt.get();
_customer.setFirstname(customer.getFirstname());
_customer.setLastname(customer.getLastname());
_customer.setAddress(customer.getAddress());
_customer.setAge(customer.getAge());
repo.save(_customer);
return _customer;
}
public void deleteCustomerById(String id) {
repo.deleteById(id);
}
}
Implement SpringBoot MongoDB CRUD RestAPIs
Related post: SpringBoot RestAPIs @GetMapping, @PostMapping, @DeleteMapping, @PutMapping, @PatchMapping
We use SpringWeb to implement 4 RestAPIs for Post/Get/Put/Delete requests as below list:
- SpringBoot Post request – we define a Post RestApi:
/api/customers/create
is used to save a single Customer data to MongoDB database. - SpringBoot Get request – we define a GET RestApi:
/api/customers/retrieveinfos
is used to retrieve all Customer documents from MongoDB database. - SpringBoot Put request – we define a restapi
/api/customers/updatebyid/{id}
to update a Customer document from MongoDB via a given id and request body’s data - SpringBoot Delete request – we define a Delete RestApi:
/api/customers/deletebyid/{id}
is used to delete a Customer document from MongoDB via a giveid
package com.loizenjava.springboot.mongodb.rest;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.loizenjava.springboot.mongodb.exception.CustomException;
import com.loizenjava.springboot.mongodb.message.ResponseMsg;
import com.loizenjava.springboot.mongodb.model.Customer;
import com.loizenjava.springboot.mongodb.service.CustomerService;
@RestController
@RequestMapping("/api/customers")
@CrossOrigin(origins = { "http://localhost:4200"})
public class WebController {
@Autowired
CustomerService customerService;
@PostMapping("/create")
public ResponseEntity<ResponseMsg> saveCustomer(@RequestBody Customer customer, HttpServletRequest request) {
try {
// save to MongoDB database
Customer _customer = customerService.saveCustomer(customer);
String message = "Upload Successfully a Customer to MongoDB with id = " + _customer.getId();
return new ResponseEntity<ResponseMsg>(new ResponseMsg(message, request.getRequestURI(),
List.of(customer)), HttpStatus.OK);
}catch(Exception e) {
String message = "Can NOT upload a Customer to MongoDB database";
return new ResponseEntity<ResponseMsg>(new ResponseMsg(message, request.getRequestURI(),
e.getMessage()), HttpStatus.OK);
}
}
@GetMapping("/retrieveinfos")
public ResponseEntity<ResponseMsg> getAllCustomers(HttpServletRequest request) {
try {
// get all documents from MongoDB database
List<Customer> customers = customerService.retrieveAllCustomers();
String message = "Retrieve all Customer successfully!";
return new ResponseEntity<ResponseMsg>(new ResponseMsg(message,
request.getRequestURI(), customers), HttpStatus.OK);
}catch(Exception e) {
String message = "Can NOT retrieve all data from MongoDB database";
return new ResponseEntity<ResponseMsg>(new ResponseMsg(message, request.getRequestURI(),
e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@PutMapping("/updatebyid/{id}")
public ResponseEntity<ResponseMsg> updateCustomer(@PathVariable String id, @RequestBody Customer customer,
HttpServletRequest request) {
try {
// update a customer to MongoDB
Customer _customer = customerService.updateCustomer(id, customer);
String message = "Successfully Update a Customer to MongoDB with id = " + id;
return new ResponseEntity<ResponseMsg> (new ResponseMsg(message, request.getRequestURI(),
List.of(_customer)), HttpStatus.OK);
} catch (CustomException ce) {
String message = "Can NOT update to MongoDB a Customer with id = " + id;
return new ResponseEntity<ResponseMsg> (new ResponseMsg(message, request.getRequestURI(),
ce.getMessage()), HttpStatus.NOT_FOUND);
} catch (Exception e) {
String message = "Can NOT update to MongoDB a Customer with id = " + id;
return new ResponseEntity<ResponseMsg> (new ResponseMsg(message, request.getRequestURI(),
e.getMessage()), HttpStatus.INTERNAL_SERVER_ERROR);
}
}
@DeleteMapping("/deletebyid/{id}")
public ResponseEntity<ResponseMsg> deleteCustomerById(@PathVariable String id, HttpServletRequest request) {
try {
// delete a Customer from MongoDB database using ID
customerService.deleteCustomerById(id);
String message = "Successfully delete a Customer from MongoDB database with id = " + id;
return new ResponseEntity<ResponseMsg>(new ResponseMsg(message, request.getRequestURI()), HttpStatus.OK);
} catch(Exception e) {
String message = "Can Not delete a Customer from MongoDB database with id = " + id;
return new ResponseEntity<ResponseMsg>(new ResponseMsg(message, request.getRequestURI(), e.getMessage()),
HttpStatus.INTERNAL_SERVER_ERROR);
}
}
}
Integrative Testing – SpringBoot MongoDB CRUD RestAPIs testsuite
Testcase 1 – Post request – Save a single object to MongoDB

– Check MongoDB document after Posting data:

Testcase 2 – Get request – retrieve all documents from MongoDB

Testcase 3 – Put request – SpringBoot RestAPI updates data to MongoDB

– Check MongoDB document after updating:

Testcase 4 – Delete request – SpringBoot RestAPI delete a single document from MongoDB

Angular 8 CRUD Application Example – Frontend Development
Angular 8 CRUD Application Overview with SpringBoot RestAPIs

– For more details, we go back to the session: Angular 8 CRUD Design
Create Angular 8 Application
We create Angular 8 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;
Create Angular Typescript Model
We define Customer
class with 5 attributes:
export class Customer {
id: number;
firstname: string;
lastname: string;
age: number;
address: string
}
Create Typescript Message
We define Message
class as below:
import { Customer } from './customer';
export class Message {
message: string;
error: string;
customers: Customer[];
}
Implement Angular 8 CRUD HttpClient 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 8 HttpClient Post request
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 8 HttpClient Get request
– Angular Client retrieve all data from MongoDB via SpringBoot RestAPIs backend 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 8 HttpClient Put request
– Angular 8 client updates a data using Angular 8 built-in 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 8 HttpClient Delete request
– Angular 8 client deletes a data from MongoDB by a given id
using built-in Angular 8 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)
);
}
Implement Angular 8 post/get/put/delete components
Implement Angular 8 Message Service
For tracking the proccessing of each step of Angular 8 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 = [];
}
}
Implement Angular 8 Post Component: adding data
AddCustomerComponent
is used to post a new data Customer to MongoDB via SpringBoot CRUD Application server.
– We have 2 parts:
add-customer.component.ts
fileadd-cusomer.component.html
file
1. add-customer.component.ts
file
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();
}
}
2. 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>
Implement Angular 8 List Component: retrieve all data
ListCustomersComponent
has 4 main functions:
- Show all Customers
- Show details a Customers
- Delete a Customer
- Update a Customer
1. 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();
}
}
2. 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>
Implement Angular 8 Message Component
MessageComponent
is used to show all tracing-log messages in html view.
1. 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) {}
}
2. 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>
Configure Angular 10 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 for “Angular 10 SpringBoot MongoDB CRUD Example”:
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 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>
Integrative Testing: Angular 8 Application with SpringBoot CRUD RestAPIs + MongoDB
Okay, now we do a set of testcases for the tutorial: “Angular 8 SpringBoot MongoDB CRUD Example using SpringData and Atlas MongoDB”.
Testcase 1: Angular 8 Post data to MongoDB through SpringBoot RestAPI
– Network Logging:

– Angular 8 Post data:

– Angular 8 Message Logs:

Testcase 2: Angular Get All data from MongoDB through SpringBoot RestAPI
– Network Logging:

– Angular 8 List documents:

Testcase 3: Angular 8 Put data to MongoDB through SpringBoot RestAPI
– Network Logging:

– Angular 8 Update Successfully:

Testcase 4: Angular 8 Delete data from MongoDB through SpringBoot RestAPI

– Check MongoDB after doing CRUD requests:

Sourcecode
Below is clearly running sourcecode for the tutorial “Angular 8 SpringBoot MongoDB CRUD Example” with SpringData Mongo and Atlas MongoDB”:
1. SpringBoot MongoDB RestAPIs:
2. Angular 8 CRUD Application:
– GitHub Sourcecode:
SpringBoot MongoDB CRUD RestAPI Example