Angular 6 HttpClient + Node.js/Express RestAPIs + MariaDB example | Sequelize ORM CRUD APIs example

In this tutorial, we show you Angular 6 Http Client & Node.js/Express Server example that uses Sequelize ORM to do CRUD with MariaDB and Angular 6 as a front-end technology to make request and receive response.

Related posts:
Mongoose CRUD MongoDB – Angular 6 HttpClient Get/Post/Put/Delete – Node.js/Express RestAPIs
Angular 6 HttpClient – Upload Files/Download Files to MySQL with Node.js/Express RestAPIs – using Multer + Sequelize ORM
Angular 6 HttpClient – PostgreSQL – Node.js/Express Sequelize CRUD APIs – Post/Get/Put/Delete

Related Pages:

I. Technologies

– Java 1.8
– Maven 3.3.9
– Node.js/Express
– Sequelize ORM
– Angular 6
– RxJS 6
– MariaDB

II. Overview

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + overview architecture

1. Node.js Server

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + node.js-design-architecture

2. Angular 6 Client

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + angular-6-project-component-architecture

III. Practice

1. Project Structure

1.1 Node.js Server

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + node.js-project-structure

customer.model.js file corresponds to entity and table customer.
customer.controller.js is used to interact with MariaDB via CRUD APIs of Sequelize ORM.
customer.route.js is used to configure Express RestAPIs.
– Configuration for MariaDB Datasource and Sequelize ORM properties in env.js and db.config.js

1.2 Angular 6 Client

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + angular-6-project-structure

In this example, we focus on:
– 4 components: customers-list, customer-details, create-customer, search-customer.
– 3 modules: FormsModule, HttpClientModule, AppRoutingModule.
customer.ts: class Customer (id, firstName, lastName)
customer.service.ts: Service for Http Client methods

2. How to do

2.1 Node.js Server
2.1.1 Setup NodeJs/Express Project

Following the guide to create a NodeJS/Express project.
Install Sequelize & MariaDB:

$npm install sequelize mysql2 cors--save

-> package.json file:

{
  "name": "nodejs-express-sequelizejs-mariadb",
  "version": "1.0.0",
  "description": "nodejs-express-sequelizejs-mariadb",
  "main": "server.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "Node.js-Express-SequelizeJS-MariaDB"
  ],
  "author": "Grokonez.com",
  "license": "ISC",
  "dependencies": {
    "cors": "^2.8.4",
    "express": "^4.16.3",
    "mysql2": "^1.5.3",
    "sequelize": "^4.37.6"
  }
}
2.1.2 Setup Sequelize MariaDB Connection

– Create ./app/config/env.js file:

const env = {
  database: 'gkzdb',
  username: 'root',
  password: '12345',
  host: 'localhost',
  dialect: 'mysql',
  pool: {
	  max: 5,
	  min: 0,
	  acquire: 30000,
	  idle: 10000
  }
};

module.exports = env;

– Setup Sequelize-MariaDB connection in ./app/config/db.config.js file:

const env = require('./env.js');

const Sequelize = require('sequelize');
const sequelize = new Sequelize(env.database, env.username, env.password, {
  host: env.host,
  dialect: env.dialect,
  operatorsAliases: false,

  pool: {
    max: env.max,
    min: env.pool.min,
    acquire: env.pool.acquire,
    idle: env.pool.idle
  }
});

const db = {};

db.Sequelize = Sequelize;
db.sequelize = sequelize;

//Models/tables
db.customers = require('../model/customer.model.js')(sequelize, Sequelize);


module.exports = db;
2.1.3 Sequelize Model
module.exports = (sequelize, Sequelize) => {

	const Customer = sequelize.define('customer', {
	  name: {
		type: Sequelize.STRING
	  },
	  age: {
		  type: Sequelize.INTEGER
	  },
	  active: {
		  type: Sequelize.BOOLEAN,
		  defaultValue: false
	  }
	});
	
	return Customer;
}
2.1.4 Express RestAPIs

Route
-> Define Customer’s routes in ./app/controller/customer.route.js file:

module.exports = function(app) {
 
    const customers = require('../controller/customer.controller.js');
 
    // Create a new Customer
    app.post('/api/customers/create', customers.create);
 
    // Retrieve all Customer
    app.get('/api/customers', customers.findAll);
 
    // Retrieve a single Customer by Id
    app.get('/api/customers/:customerId', customers.findById);

    app.get('/api/customers/age/:age', customers.lookUpByAge);
 
    // Update a Customer with Id
    app.put('/api/customers/:customerId', customers.update);
 
    // Delete a Customer with Id
    app.delete('/api/customers/:customerId', customers.delete);

    // Delete all Customers
    app.delete('/api/customers/all/delete', customers.deleteAll);
}

Controller
-> Implement Customer’s controller in ./app/controller/customer.controller.js file:

const db = require('../config/db.config.js');
const Customer = db.customers;

// Post a Customer
exports.create = (req, res) => {	
	// Save to MariaDB database
	Customer.create({  
			name: req.body.name,
			age: req.body.age,
			active: req.body.active
		})
		.then(customer => {		
			// Send created customer to client
			res.json(customer);
		})
		.catch(error => res.status(400).send(error))
};
 
// Fetch all Customers
exports.findAll = (req, res) => {
	Customer.findAll({
			attributes: { exclude: ["createdAt", "updatedAt"] }
		})
		.then(customers => {
			res.json(customers);
		})
		.catch(error => res.status(400).send(error))
};

// Find a Customer by Id
exports.findById = (req, res) => {	
	Customer.findById(req.params.customerId,
				{attributes: { exclude: ["createdAt", "updatedAt"] }}
			)
			.then(customer => {
					if (!customer){
						return res.status(404).json({message: "Customer Not Found"})
					}
					return res.status(200).json(customer)
				}
			)
			.catch(error => res.status(400).send(error));
};

exports.lookUpByAge = (req, res) => {
	console.log("LookUByAge");
	return Customer.findAll({
				where: {
					age: req.params.age
				},
				attributes: { exclude: ["createdAt", "updatedAt"] }
			})
			.then( customers => {
					if(!customers){
						return res.status(404).json({message: "Customers Not Found"})
					}
					return res.status(200).json(customers)
				}
			)
			.catch(error => res.status(400).send(error));
}
 
// Update a Customer
exports.update = (req, res) => {
	return Customer.findById(req.params.customerId)
		.then(
			customer => {
				if(!customer){
					return res.status(404).json({
						message: 'Customer Not Found',
					});
				}
				return customer
							.update({
								name: req.body.name,
								age: req.body.age,
								active: req.body.active
							})
							.then(() => res.status(200).json(customer))
							.catch((error) => res.status(400).send(error));
				}
			)
		.catch((error) => res.status(400).send(error));			 
};
 
// Delete a Customer by Id
exports.delete = (req, res) => {
	return Customer
					.findById(req.params.customerId)
					.then(customer => {
						if(!customer) {
							return res.status(400).json({
								message: 'Customer Not Found',
							});
						}

						return customer.destroy()
										.then(() => res.status(200).json({message: "Destroy successfully!"}))
										.catch(error => res.status(400).send(error));
					})
					.catch(error => res.status(400).send(error));
};

exports.deleteAll = (req, res) => {
	return Customer.destroy({
					where: {},
					truncate: true
				})
				.then(() => res.status(200).json({message: "All customers have been deleted!"}))
				.catch(error => res.status(400).send(error));
}
2.1.5 Server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.json())

const cors = require('cors')
const corsOptions = {
  origin: 'http://localhost:4200',
  optionsSuccessStatus: 200
}
app.use(cors(corsOptions));

const db = require('./app/config/db.config.js');
  
// force: true will drop the table if it already exists
db.sequelize.sync({force: true}).then(() => {
  console.log('Drop and Resync with { force: true }');
});

require('./app/route/customer.route.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)
})
2.2 Angular 6 Client
2.2.0 Create Service & Components

Run commands below:
ng g s Customer
ng g c CreateCustomer
ng g c CustomerDetails
ng g c CustomersList
ng g c SearchCustomers
On each Component selector, delete app- prefix, then change tslint.json rules"component-selector" to false.

2.2.1 Model

customer.ts

export class Customer {
    id: number;
    name: string;
    age: number;
    active: boolean;
}
2.2.2 CustomerService

customer.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

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

  private baseUrl = 'http://localhost:8080/api/customers';

  constructor(private http: HttpClient) { }

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

  createCustomer(customer: Object): Observable {
    return this.http.post(`${this.baseUrl}` + `/create`, customer);
  }

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

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

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

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

  deleteAll(): Observable {
    return this.http.delete(`${this.baseUrl}` + `/delete`, { responseType: 'text' });
  }
}

2.2.3 Components

– CustomerDetailsComponent:
customer-details/customer-details.component.ts

import { Component, OnInit, Input } from '@angular/core';
import { CustomerService } from '../customer.service';
import { Customer } from '../customer';

import { CustomersListComponent } from '../customers-list/customers-list.component';

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

  @Input() customer: Customer;

  constructor(private customerService: CustomerService, private listComponent: CustomersListComponent) { }

  ngOnInit() {
  }

  updateActive(isActive: boolean) {
    this.customerService.updateCustomer(this.customer.id,
      { name: this.customer.name, age: this.customer.age, active: isActive })
      .subscribe(
        data => {
          console.log(data);
          this.customer = data as Customer;
        },
        error => console.log(error));
  }

  deleteCustomer() {
    this.customerService.deleteCustomer(this.customer.id)
      .subscribe(
        data => {
          console.log(data);
          this.listComponent.reloadData();
        },
        error => console.log(error));
  }
}

customer-details/customer-details.component.html

{{customer.name}}
{{customer.age}}
{{customer.active}}
Inactive Active Delete

– CustomersListComponent:
customers-list/customers-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs';

import { CustomerService } from '../customer.service';
import { Customer } from '../customer';

@Component({
  selector: 'customers-list',
  templateUrl: './customers-list.component.html',
  styleUrls: ['./customers-list.component.css']
})
export class CustomersListComponent implements OnInit {

  customers: Observable;

  constructor(private customerService: CustomerService) { }

  ngOnInit() {
    this.reloadData();
  }

  deleteCustomers() {
    this.customerService.deleteAll()
      .subscribe(
        data => {
          console.log(data);
          this.reloadData();
        },
        error => console.log('ERROR: ' + error));
  }

  reloadData() {
    this.customers = this.customerService.getCustomersList();
  }
}

customers-list/customers-list.component.html

Customers

– CreateCustomerComponent:
create-customer/create-customer.component.ts

import { Component, OnInit } from '@angular/core';

import { Customer } from '../customer';
import { CustomerService } from '../customer.service';

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

  customer: Customer = new Customer();
  submitted = false;

  constructor(private customerService: CustomerService) { }

  ngOnInit() {
  }

  newCustomer(): void {
    this.submitted = false;
    this.customer = new Customer();
  }

  save() {
    this.customerService.createCustomer(this.customer)
      .subscribe(data => console.log(data), error => console.log(error));
    this.customer = new Customer();
  }

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

create-customer/create-customer.component.html

Create Customer

You submitted successfully!

– SearchCustomersComponent:
search-customers/search-customers.component.ts

import { Component, OnInit } from '@angular/core';
import { Customer } from '../customer';
import { CustomerService } from '../customer.service';

@Component({
  selector: 'search-customers',
  templateUrl: './search-customers.component.html',
  styleUrls: ['./search-customers.component.css']
})
export class SearchCustomersComponent implements OnInit {

  age: number;
  customers: Customer[];

  constructor(private dataService: CustomerService) { }

  ngOnInit() {
    this.age = 0;
  }

  private searchCustomers() {
    this.dataService.getCustomersByAge(this.age)
      .subscribe(customers => this.customers = customers);
  }

  onSubmit() {
    this.searchCustomers();
  }
}

search-customers/search-customers.component.html

Find By Age

  • {{customer.id}} - {{customer.name}} {{customer.age}}

2.2.4 AppRoutingModule

app-routing.module.ts

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CustomersListComponent } from './customers-list/customers-list.component';
import { CreateCustomerComponent } from './create-customer/create-customer.component';
import { SearchCustomersComponent } from './search-customers/search-customers.component';

const routes: Routes = [
    { path: '', redirectTo: 'customer', pathMatch: 'full' },
    { path: 'customer', component: CustomersListComponent },
    { path: 'add', component: CreateCustomerComponent },
    { path: 'findbyage', component: SearchCustomersComponent },
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})

export class AppRoutingModule { }

And AppComponent HTML for routing:
app.component.html

{{title}}

{{description}}

2.2.5 AppModule

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { CreateCustomerComponent } from './create-customer/create-customer.component';
import { CustomerDetailsComponent } from './customer-details/customer-details.component';
import { CustomersListComponent } from './customers-list/customers-list.component';
import { SearchCustomersComponent } from './search-customers/search-customers.component';
import { AppRoutingModule } from './app-routing.module';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    CreateCustomerComponent,
    CustomerDetailsComponent,
    CustomersListComponent,
    SearchCustomersComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

3. Run & Check Result

Run Node.js project with commandlines: npm start.
– Run the Angular App with command: ng serve.

– Open browser for url http://localhost:4200/:
Add Customer:

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + add-customer

Show Customers:

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + get-all-customer

Click on Active button to update Customer status:

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + update-customer

Search Customers by Age:

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + search-by-age

Delete a Customer:

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + delete-a-customer

Delete All Customers:

angular-6-crud-httpclient-nodejs-express-rest-api-sequelize-orm-crud-mariadb + delete-all

IV. Source Code

Nodejs-Express-Sequelizejs-MariaDB
Angular6SpringBoot-Client

0 0 votes
Article Rating
Subscribe
Notify of
guest
95 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
95
0
Would love your thoughts, please comment.x
()
x