In the tutorial, I introduce how to build an “Angular 8 Nodejs MongoDB CRUD Example RestAPIs” project with the help of Express Web Framework and Mongoose ODM for POST/GET/PUT/DELETE requests with step by step coding examples:
– I draw a fullstack overview Diagram Architecture from Angular 8 Frontend to MongoDB database through Nodejs RestAPI backend.
– Develop Nodejs CRUD RestAPIs with the supporting of Express Rest Framework.
– Implement Angular 8 CRUD application with the Angular 8 Httpclient to do CRUD request (Post/Get/Put/Delete) to Nodejs 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 Nodejs RestAPIs Server and save/retrieve data to MongoDB database.
- Overview Example – How to build Angular 8 MongoDB Nodejs CRUD Example?
- Nodejs MongoDB Atlas Express Mongoose CRUD RestAPIs Example – Backend Development
- Angular 8 CRUD Application Example – Frontend Development
- Angular 8 CRUD Application Overview with Nodejs 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 Nodejs CRUD RestAPIs + MongoDB
- Sourcecode
- Further Reading
Overview Example – How to build Angular 8 MongoDB Nodejs CRUD Example?
Overall Architecture System: Angular 8 + Nodejs + MongoDB

- We build a backend: Nodejs CRUD Express Mongoose 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 Nodejs CRUD application and display corresponding data in Angular Component.
Nodejs Express Mongoose CRUD Design Application

Our Nodejs CRUD Application has 4 main blocks:
- To build RestAPIs in Node.js application, we use Express framework.
- To do CRUD operations with MongoDB database, we use Mongoose ODM queries.
- We define Nodejs RestAPI URLs in router.js file
- We implement the logic: how to process each RestAPI in controller.js file

config
package is used to configure MongoDB database environmentmodels
package is used to define Mongoose schema model to interact with MongoDB databaserouters
package is used to define RestAPI’ URLscontrollers
is used to implement Nodejs business logic to process each RestAPI
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 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 navigation URLs mapping with the corresponding Angular Components

Angular CRUD Application defines 3 components, 2 services, 1 routers, and 2 data models:
– Angular 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 Services:
customer.service.ts
defines CRUD Angular httpclient post/get/put/delete requests to Node.js Express RestAPIsmessage.service.ts
defines an array storage to log all messages when the Angular 8 CRUD App running
– Angular 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 application.message.ts
defines the response data model between Nodejs and Angular application.
Project Goal
– Angular adds a data:

– Angular Nodejs MongoDB list all data:


– Angular update a data:

– Delete a record:

– Check all MongoDB’s documents:

Nodejs MongoDB Atlas Express Mongoose CRUD RestAPIs Example – Backend Development
Create Nodejs Express Project
To development a ‘Node.js MongoDB CRUD Example with Mongoose and Express RestAPIs’, we need a set of packages to handle the full stack of the web backend proccessing, they includes Express framework, Cors, Body Parse, Mongoose packages.
- Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications.
$ npm install express
- CORS is a node.js package for providing a Connect/Express middleware that can be used to enable CORS with various options.
$ npm install cors
- Body-parser is the Node.js body parsing middleware. It is responsible for parsing incoming request bodies in a middleware before your handlers, available under the
req.body
property.$ npm install body-parser
- Mongoose is a promise-based Node.js ODM for MongoDB.
$ npm install --save mongoose
We can install all the packages by one cmd:
$npm install --save express cors body-parser pg pg-hstore mongoose
Check package.json
file is created as below content:
{
"name": "nodejs-express-mongodb-crud-example",
"version": "1.0.0",
"description": "Nodejs Express CRUD RestAPIs with Mongoose Example",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "https://github.com/loizenjava"
},
"keywords": [
"nodejs",
"crud",
"restapi",
"mongoose",
"example",
"express"
],
"author": "https://loizenjava.com",
"license": "ISC",
"dependencies": {
"body-parser": "^1.19.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"mongoose": "^5.10.2",
"sequelize": "^6.3.4"
}
}
MongoDB Atlas Configuration
We create a file mongodb.config.js
as below:
module.exports = {
url: 'mongodb+srv://loizenjava:loizenjava@cluster0.esvi3.mongodb.net/loizenjavadb'
}
Define Mongoose Model
In the tutorial, ‘Angular 8 Node.js Express MongoDB RestAPIs Example’, We need define a Mongoose ODM model to represent a document in the customer collection, see details of coding in file customer.model.js
:
const mongoose = require('mongoose');
const CustomerSchema = mongoose.Schema({
firstname: String,
lastname: String,
address: String,
age: {
type: Number,
min: 18,
max: 65,
required: true
},
copyrightby: {
type: String,
default: 'https://loizenjava.com'
}
});
module.exports = mongoose.model('Customer', CustomerSchema);
Define Nodejs Express RestAPIs Router
I define 4 URLs for Nodejs CRUD RestAPIs with MongoDB:
/api/customers/create
is Post restApi to do a post request/api/customers/retrieveinfos
is a Get restApi to retrieve all records from MongoDB/api/customers/updatebyid/:id
is a Put RestAPI to update a data by a givenid
/api/customers/deletebyid/:id
is a Delete RestApi to delete a data by a givenid
– Detail Coding:
module.exports = function(app) {
var customers = require('../controllers/customer.controller.js');
// Create a new Customer
app.post('/api/customer/create', customers.create);
// Retrieve all Customer
app.get('/api/customer/retrieveinfos', customers.findall);
// Update a Customer with Id
app.put('/api/customer/updatebyid/:id', customers.update);
// Delete a Customer with Id
app.delete('/api/customer/deletebyid/:id', customers.delete);
}
Implement Fullstack Nodejs Express Mongoose CRUD RestAPIs with MongoDB
To process CRUD Post/Get/Put/Delete RestAPI requests, we implement a file controller.js
with 4 functions:
exports.create = (req, res)
is used to create a new posting data to MongoDB (Nodejs Post request)exports.retrieveInfos = (req, res)
is used to retrieve all data’s infos from MongoDB database (Nodejs Get Request)exports.updateById = async (req, res)
is used to update a data from MongoDB with a given id (Nodejs PUT request)exports.deleteById = async (req, res)
is used to delete a customer with a given id (Nodejs Delete request)
Nodejs Post request
create = (req, res)
function is used to handle a POST
request at the endpoint /api/customer/create
, save data to MongoDB database and return back a JSON message.
What will we do?
- Create a Customer object from a request’s body data
- Use the Mongoose Model to save created object to MongoDB database
- Return back a JSON message to client side
Remember to use the catch
statement for handling any error if having unexpected exception.
exports.create = (req, res) => {
const customer = new Customer({
firstname: req.body.firstname,
lastname: req.body.lastname,
age: req.body.age,
address: req.body.address,
});
// Save a Customer in the MongoDB
customer.save().then(data => {
// send uploading message to client
res.status(200).json({
message: "Upload Successfully a Customer to MongoDB with id = " + data.id,
customer: data,
});
}).catch(err => {
res.status(500).json({
message: "Fail!",
error: err.message
});
});
};
Nodejs Get request
Now we implement fullstack from Nodejs Express GET request using Mongoose ODM to retrieve data from MongoDB database. We create a GET request methods: findall = (req, res)
function is used to handle a GET request at the endpoint /api/customers/retrieveinfos
to fetch all documents from MongoDB and return back to client in JSON format
How to implement findall = (req, res)
function? It’s so simple
- Using
Customer.find()
function to fetch all documents from MongoDB database - Return a JSON message to client with needed information
- Do not forget to handle any unexpected error by using
catch
statement if having any exception throwed
exports.findall = (req, res) => {
Customer.find().select('-__v').then(customerInfos => {
res.status(200).json({
message: "Get all Customers' Infos Successfully!",
numberOfCustomers: customerInfos.length,
customers: customerInfos
});
}).catch(error => {
// log on console
console.log(error);
res.status(500).json({
message: "Error!",
error: error
});
});
};
Nodejs Delete request
exports.delete = (req, res)
function is used to handle a DELETE request at the endpoint /api/customer/deletebyid/:id
to delete a specific document from MongoDB database with a given id
from the path parameter.
How to implement it?
- Using the Mongoose Model’s function:
findByIdAndRemove
to check the existence of a specific document in MongoDB database with a givenid
:Customer.findByIdAndRemove(customerId)
- If it does NOT existed, return a 404 NOT-FOUND message
- Otherwise, the Mongoose model’s function:
findByIdAndRemove
will delete the document in MongoDB database then returns back a successfully message with 200 status code to client side - Do not forget to handle any unexpected error by using a
catch
statement
– Coding :
exports.delete = (req, res) => {
let customerId = req.params.id
Customer.findByIdAndRemove(customerId).select('-__v -_id')
.then(customer => {
if(!customer) {
res.status(404).json({
message: "Does Not exist a Customer with id = " + customerId,
error: "404",
});
}
res.status(200).json({
message: "Delete Successfully a Customer with id = " + customerId,
customer: customer,
});
}).catch(err => {
return res.status(500).send({
message: "Error -> Can NOT delete a customer with id = " + customerId,
error: err.message
});
});
};
Nodejs Put request
Now we implement a fullstack solution: Nodejs Express RestAPI PUT request to get data from MongoDB using Mongoose ODM.
update = (req, res)
function is used to handle a PUT request at the endpoint /api/customer/updatebyid/:id
to update a specific document from MongoDB database with a given id
How to implement it? Just simple:
- Use Mongoose ODM Model’s function:
findByIdAndUpdate()
to fetch a specific Customer with a givenid
from request parameter:
Customer.findByIdAndUpdate(req.params.id, ...)
- If existing a specific instance with the given
id
, it will update new values from body request to the founded Customer object and save the object again to MongoDB database, then returns back to client a Json message with200
status code:res.status(200).json({ message: "Update successfully a Customer with id = " + req.params.id, customer: customer, });
- If not found a document with a given id, it will return back to client a Json message with
404
status code:if(!customer) { return res.status(404).send({ message: "Error -> Can NOT update a customer with id = " + req.params.id, error: "Not Found!" }); }
- Don’t forget to use a
catch
statement to handle any unexpected-exception
– Coding:
exports.update = (req, res) => {
// Find customer and update it
Customer.findByIdAndUpdate(
req.params.id,
{
firstname: req.body.firstname,
lastname: req.body.lastname,
age: req.body.age
},
{new: true}
).select('-__v')
.then(customer => {
if(!customer) {
return res.status(404).send({
message: "Error -> Can NOT update a customer with id = " + req.params.id,
error: "Not Found!"
});
}
res.status(200).json({
message: "Update successfully a Customer with id = " + req.params.id,
customer: customer,
});
}).catch(err => {
return res.status(500).send({
message: "Error -> Can not update a customer with id = " + req.params.id,
error: err.message
});
});
};
Create Nodejs Express Server with MongoDB Connection
To implement an Express RestAPIs Application, firstly we need create a server with express app:
– server.js
:
const express = require('express');
const app = express();
...
const server = app.listen(8080, function () {
let host = server.address().address
let port = server.address().port
console.log("App listening at http://%s:%s", host, port);
})
– For parsing body of requests, we need use body-parser
dependency, add more code on server.js
file:
...
var bodyParser = require('body-parser');
...
app.use(bodyParser.json());
...
const server = app.listen(8080, function () {
...
>
– To connect with MongoDB, we use below segment code:
mongoose.connect(dbConfig.url, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("Successfully connected to MongoDB.");
}).catch(err => {
console.log('Could not connect to MongoDB.');
process.exit();
});
Here is all coding in the server.js
file:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json())
// Configuring the database
const dbConfig = require('./app/config/mongodb.config.js');
const mongoose = require('mongoose');
mongoose.Promise = global.Promise;
// Connecting to the database
mongoose.connect(dbConfig.url, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => {
console.log("Successfully connected to MongoDB.");
}).catch(err => {
console.log('Could not connect to MongoDB.');
process.exit();
});
require('./app/routes/customer.router.js')(app);
// Create a Server
var server = app.listen(8080, function () {
var host = server.address().address
var port = server.address().port
console.log("App listening at http://%s:%s", host, port)
})
Backend Testing: Nodejs MongoDB Express Mongoose CRUD RestAPIs
Testcase 1: Nodejs Post request

Check MongoDB documents:

Testcase 2: Nodejs Get request – Retrieve all records in MongoDB

Testcase 3: Nodejs Put request – Update a record by given id

– Check MongoDB document:


Testcase 4: Nodejs Delete request – Remove a record by given id

– Check MongoDB documents after doing CRUD requests:

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

– For more details, we go back to the session: Angular 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 Nodejs Express CRUD 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 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 Nodejs 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 8 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 8 Nodejs PostgreSQL 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 Nodejs CRUD RestAPIs + MongoDB
Okay, now we do a set of testcases for the tutorial: “Angular 8 Node.js MongoDB CRUD Example using Express and Mongoose ODM”.
Testcase 1: Angular 8 Post data to MongoDB
– Network Logging:

– Angular Post data:

– Angular Message Logs:

Testcase 2: Angular 8 Get All data from MongoDB
– Network Logging:

– Angular List documents:

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

– Angular Update Successfully:

Testcase 4: Angular 8 Delete data from MongoDB

– Check MongoDB after doing CRUD requests:

Sourcecode
Below is clearly running sourcecode for the tutorial “Angular 8 Nodejs MongoDB CRUD Example with Mongoose ODM and Express framework”:
1. Nodejs Mongoose ODM CRUD Application
Nodejs-Express-MongoDB-CRUD-Example
2. Angular 8 CRUD Application:
– Github sourcecode for the tutorial: “Angular 8 Nodejs MongoDB CRUD Example”
1. Nodejs MongoDB CRUD Application:
2. Angular 8 CRUD Application: