Angular 16 + node js express MySQL crud; Through this tutorial, i am going to show you how to create a crud apps in Angular 16 using node js + Express Rest API + MySQL db.
Angular 16 CRUD + Node.js + Express + MySQL Example Tutorial
Use the below given steps and create Angular 16 + node js express mysql crud; as follows:
- Step 1 – Create Node JS + Express + MySQL App
- Step 2 – Create New Angular App
- Step 3 – Create Components in Angular
- Step 4 – Import Modules in app.module.ts
- Step 5 – Create CRUD Routes
- Step 6 – Create Services for Consumption of Node js REST API
- Step 7 – Add code In app.component.html
- Step 8 – Create Operation
Step 1 – Create Node JS + Express + MySQL App
To make RESTful API using Node and Express.js with MySQL database. So, run the below command to invoke the REST API development with Node and Express.js:
mkdir nodejs-express-sequelize-mysql cd nodejs-express-sequelize-mysql
Then execute:
npm init -y
After that, execute the following commands to install imperative npm packages which will help us to create REST APIs for our Angular CRUD system:
npm install express sequelize mysql2 body-parser cors --save
The package.json file should look like this:
{ "name": "nodejs-express-sequelize-mysql", "version": "1.0.0", "description": "Node.js Rest Apis with Express, Sequelize & MySQL", "main": "server.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [ "nodejs", "express", "rest", "api", "sequelize", "mysql" ], "author": "lara", "license": "ISC", "dependencies": { "cors": "^2.8.5", "express": "^4.17.1", "mysql2": "^2.0.2", "sequelize": "^5.21.2" } }
Create a separate config folder for configuration with db.config.js file like this:
module.exports = { HOST: "localhost", USER: "root", PASSWORD: "123456", DB: "testdb", dialect: "mysql", pool: { max: 5, min: 0, acquire: 30000, idle: 10000 } };
Now, you need to create the Book model or schema, create node-backend/models directory. Also create a Book.js file and add the below code into it:
module.exports = (sequelize, Sequelize) => { const Book = sequelize.define("tutorial", { title: { type: Sequelize.STRING }, price: { type: Sequelize.STRING }, description: { type: Sequelize.STRING } }); return Book; };
Then initialize Sequelize in /models folder that will contain model in the next step.
Now create /models/index.js with the following code:
const dbConfig = require("../config/db.config.js"); const Sequelize = require("sequelize"); const sequelize = new Sequelize(dbConfig.DB, dbConfig.USER, dbConfig.PASSWORD, { host: dbConfig.HOST, dialect: dbConfig.dialect, operatorsAliases: false, pool: { max: dbConfig.pool.max, min: dbConfig.pool.min, acquire: dbConfig.pool.acquire, idle: dbConfig.pool.idle } }); const db = {}; db.Sequelize = Sequelize; db.sequelize = sequelize; db.books= require("./books.js")(sequelize, Sequelize); module.exports = db;
Don’t forget to call sync()
method in server.js:
... const app = express(); app.use(...); const db = require("./app/models"); db.sequelize.sync(); ...
Then, You need to define the REST API routes using Express js in a node project. Create node-backend/routes directory, also create book.routes.js file, Add the below code into it:
const express = require('express'); const app = express(); const bookRoute = express.Router(); let Book = require('../models/Book'); // Add Book bookRoute.route('/add-book').post((req, res, next) => { Book.create(req.body, (error, data) => { if (error) { return next(error) } else { res.json(data) } }) }); // Get all Book bookRoute.route('/').get((req, res) => { Book.find((error, data) => { if (error) { return next(error) } else { res.json(data) } }) }) // Get Book bookRoute.route('/read-book/:id').get((req, res) => { Book.findById(req.params.id, (error, data) => { if (error) { return next(error) } else { res.json(data) } }) }) // Update Book bookRoute.route('/update-book/:id').put((req, res, next) => { Book.findByIdAndUpdate(req.params.id, { $set: req.body }, (error, data) => { if (error) { return next(error); console.log(error) } else { res.json(data) console.log('Book updated successfully!') } }) }) // Delete Book bookRoute.route('/delete-book/:id').delete((req, res, next) => { Book.findByIdAndRemove(req.params.id, (error, data) => { if (error) { return next(error); } else { res.status(200).json({ msg: data }) } }) }) module.exports = bookRoute;
Now, you need to sum up all the code and conjugate it in one place so that you can run our backend and propel the CRUD app development forward.
Create and add the below code in the server.js file:
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cors = require("cors"); var bodyParser = require('body-parser'); var corsOptions = { origin: "http://localhost:8081" }; app.use(cors(corsOptions)); const bookRoute = require('./routes/book.routes') const app = express(); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(cors()); // Static directory path app.use(express.static(path.join(__dirname, 'dist/angular-mean-crud-tutorial'))); // API root app.use('/api', bookRoute) // PORT const port = process.env.PORT || 8000; app.listen(port, () => { console.log('Listening on port ' + port) }) // 404 Handler app.use((req, res, next) => { next(createError(404)); }); // Base Route app.get('/', (req, res) => { res.send('invaild endpoint'); }); app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist/angular-mean-crud-tutorial/index.html')); }); // error handler app.use(function (err, req, res, next) { console.error(err.message); if (!err.statusCode) err.statusCode = 500; res.status(err.statusCode).send(err.message); });
Step 2 – Create New Angular App
Run the following command on terminal to install Angular 16 app:
ng new angular-mean-crud-tutorial
Then execute the following command on terminal to install angular material:
ng add @angular/material
Step 3 – Create CRUD Components in Angular
Run the following commands on terminal to generate components in our angular application. So, open y cour terminal and execute the following command:
ng g c components/add-book ng g c components/book-detail ng g c components/books-list
Step 4 – Import Modules in app.module.ts
Then go to src/app directory and open app.module.ts file. Then add the following code into it:
... ... import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpClientModule } from '@angular/common/http'; @NgModule({ declarations: [], imports: [ FormsModule, HttpClientModule, ReactiveFormsModule ], providers: [], bootstrap: [] }) export class AppModule { }
Step 5 – Create CRUD Routes
Create routes; with the help of Angular routes. So, you will make the consensus with components to enable the navigation in the CRUD application so add the below code in the app-routing.module.ts file.
import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { BooksListComponent } from './components/books-list/books-list.component'; import { AddBookComponent } from './components/add-book/add-book.component'; import { BookDetailComponent } from './components/book-detail/book-detail.component'; const routes: Routes = [ { path: '', pathMatch: 'full', redirectTo: 'add-book' }, { path: 'books-list', component: BooksListComponent }, { path: 'add-book', component: AddBookComponent }, { path: 'edit-book/:id', component: BookDetailComponent } ]; @NgModule({ imports: [RouterModule.forRoot(routes)], exports: [RouterModule] }) export class AppRoutingModule { }
Step 6 – Create Services for Consumption of Node js REST API
Then go to app/service directory in Angular project and create Book.ts class within.
Then, add the below code in app/service/Book.ts file:
export class Book { _id!: String; name!: String; price!: String; description!: String; }
Then, execute the command to create crud service file:
ng g s service/crud
Then, add the below code in app/service/crud.service.ts file:
import { Injectable } from '@angular/core'; import { Book } from './Book'; import { catchError, map } from 'rxjs/operators'; import { Observable, throwError } from 'rxjs'; import { HttpClient, HttpHeaders, HttpErrorResponse } from '@angular/common/http'; @Injectable({ providedIn: 'root' }) export class CrudService { // Node/Express API REST_API: string = 'http://localhost:8000/api'; // Http Header httpHeaders = new HttpHeaders().set('Content-Type', 'application/json'); constructor(private httpClient: HttpClient) { } // Add AddBook(data: Book): Observable<any> { let API_URL = `${this.REST_API}/add-book`; return this.httpClient.post(API_URL, data) .pipe( catchError(this.handleError) ) } // Get all objects GetBooks() { return this.httpClient.get(`${this.REST_API}`); } // Get single object GetBook(id:any): Observable<any> { let API_URL = `${this.REST_API}/read-book/${id}`; return this.httpClient.get(API_URL, { headers: this.httpHeaders }) .pipe(map((res: any) => { return res || {} }), catchError(this.handleError) ) } // Update updateBook(id:any, data:any): Observable<any> { let API_URL = `${this.REST_API}/update-book/${id}`; return this.httpClient.put(API_URL, data, { headers: this.httpHeaders }) .pipe( catchError(this.handleError) ) } // Delete deleteBook(id:any): Observable<any> { let API_URL = `${this.REST_API}/delete-book/${id}`; return this.httpClient.delete(API_URL, { headers: this.httpHeaders}).pipe( catchError(this.handleError) ) } // Error handleError(error: HttpErrorResponse) { let errorMessage = ''; if (error.error instanceof ErrorEvent) { // Handle client error errorMessage = error.error.message; } else { // Handle server error errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`; } console.log(errorMessage); return throwError(errorMessage); } }
Step 7 – Add code In app.component.html
Create html and for crud app in angular. So, go to src/app/app.component.html and update the following code into it:
<nav class="navbar navbar-expand-lg navbar-light bg-light"> <a class="navbar-brand">Angular 16 CRUD Operations Demo</a> <div id="navbarNav" class="collapse navbar-collapse"> <ul class="navbar-nav ml-auto "> <li class="nav-item"> <a class="nav-link" routerLinkActive="active" routerLink="/books-list">Show Books</a> </li> <li class="nav-item"> <a class="nav-link" routerLinkActive="active" routerLink="/add-book">Add Books</a> </li> </ul> </div> </nav> <router-outlet></router-outlet>
Step 8 – Create Operation
After that, Add the code in add-book.component.ts file:
import { Component, OnInit, NgZone } from '@angular/core'; import { Router } from '@angular/router'; import { CrudService } from './../../service/crud.service'; import { FormGroup, FormBuilder } from "@angular/forms"; @Component({ selector: 'app-add-book', templateUrl: './add-book.component.html', styleUrls: ['./add-book.component.scss'] }) export class AddBookComponent implements OnInit { bookForm: FormGroup; constructor( public formBuilder: FormBuilder, private router: Router, private ngZone: NgZone, private crudService: CrudService ) { this.bookForm = this.formBuilder.group({ name: [''], price: [''], description: [''] }) } ngOnInit() { } onSubmit(): any { this.crudService.AddBook(this.bookForm.value) .subscribe(() => { console.log('Data added successfully!') this.ngZone.run(() => this.router.navigateByUrl('/books-list')) }, (err) => { console.log(err); }); } }
Then, Add the code in add-book.component.html file:
<div class="row justify-content-center mt-5"> <div class="col-md-4"> <form [formGroup]="bookForm" (ngSubmit)="onSubmit()"> <div class="form-group"> <label>Name</label> <input class="form-control" type="text" formControlName="name" required> </div> <div class="form-group"> <label>Price</label> <input class="form-control" type="text" formControlName="price" required> </div> <div class="form-group"> <label>Description</label> <input class="form-control" type="text" formControlName="description" required> </div> <div class="form-group"> <button class="btn btn-primary btn-block" type="submit">Add Book</button> </div> </form> </div> </div>
Add the code in books-list.component.ts file:
import { Component, OnInit } from '@angular/core'; import { CrudService } from './../../service/crud.service'; @Component({ selector: 'app-books-list', templateUrl: './books-list.component.html', styleUrls: ['./books-list.component.scss'] }) export class BooksListComponent implements OnInit { Books:any = []; constructor(private crudService: CrudService) { } ngOnInit(): void { this.crudService.GetBooks().subscribe(res => { console.log(res) this.Books =res; }); } delete(id:any, i:any) { console.log(id); if(window.confirm('Do you want to go ahead?')) { this.crudService.deleteBook(id).subscribe((res) => { this.Books.splice(i, 1); }) } } }
Add the code in books-list.component.html file:
<div class="container"> <div class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"> <h2 class="h2">Books List</h2> </div> <div class="table-responsive"> <table class="table table-bordered"> <thead> <tr> <th scope="col">Id</th> <th scope="col">Name</th> <th scope="col">Price</th> <th scope="col">Description</th> <th class="text-center" scope="col">Action</th> </tr> </thead> <tbody> <tr *ngFor="let book of Books; let i = index"> <th scope="row">{{book._id}}</th> <td>{{book.name}}</td> <td>{{book.price}}</td> <td>{{book.description}}</td> <td class="text-center"> <button class="btn btn-sm btn-primary" routerLink="/edit-book/{{book._id}}">Edit</button> <button class="btn btn-sm btn-danger" (click)="delete(book._id, i)">Delete</button> </tr> </tbody> </table> </div> </div>
Add the code in book-detail.component.ts file:
import { Component, OnInit, NgZone } from '@angular/core'; import { Router, ActivatedRoute } from '@angular/router'; import { CrudService } from './../../service/crud.service'; import { FormGroup, FormBuilder } from "@angular/forms"; @Component({ selector: 'app-book-detail', templateUrl: './book-detail.component.html', styleUrls: ['./book-detail.component.scss'] }) export class BookDetailComponent implements OnInit { getId: any; updateForm: FormGroup; constructor( public formBuilder: FormBuilder, private router: Router, private ngZone: NgZone, private activatedRoute: ActivatedRoute, private crudService: CrudService ) { this.getId = this.activatedRoute.snapshot.paramMap.get('id'); this.crudService.GetBook(this.getId).subscribe(res => { this.updateForm.setValue({ name: res['name'], price: res['price'], description: res['description'] }); }); this.updateForm = this.formBuilder.group({ name: [''], price: [''], description: [''] }) } ngOnInit() { } onUpdate(): any { this.crudService.updateBook(this.getId, this.updateForm.value) .subscribe(() => { console.log('Data updated successfully!') this.ngZone.run(() => this.router.navigateByUrl('/books-list')) }, (err) => { console.log(err); }); } }
Add the code in book-detail.component.html file:
<div class="row justify-content-center mt-5"> <div class="col-md-4"> <form [formGroup]="updateForm" (ngSubmit)="onUpdate()"> <div class="form-group"> <label>Name</label> <input class="form-control" type="text" formControlName="name" required> </div> <div class="form-group"> <label>Price</label> <input class="form-control" type="text" formControlName="price" required> </div> <div class="form-group"> <label>Description</label> <input class="form-control" type="text" formControlName="description" required> </div> <div class="form-group"> <button class="btn btn-primary btn-block" type="submit">Update</button> </div> </form> </div> </div>
Conclusion
Angular 16 CRUD + Node.js + Express + MySQL. In this tutorial, you have learned how to create crud app in Angular 16 using node js + express and MySQL DB with REST API.