Angular 18 CRUD Operations using Node JS MySQL
In this post, I will show you crud operations in angular 18 with node js mysql. This example will help you with angular 18 crud with node js and MySQL. I want to show you crud angular 18 node js mysql. This is a simple example of angular 18 crud workflow using node js express mysql.
Angular 18 CRUD with Node.js Express and MySQL Database enables creating, reading, updating, and deleting data in a web application. Angular 18 handles the user interface, Node.js serves as the backend, and MySQL stores the data. CRUD operations involve creating new data, reading existing data, updating data, and deleting data. Together, they form a powerful combination for building dynamic web applications that interact with a database seamlessly. This setup streamlines the process of managing data within web applications, offering users a smooth and efficient experience.
In this example, we are using node.js express to create a posts rest API. We use mysql to store data in mysql database. We then proceed with the CRUD (Create, Read, Update, Delete) operation for the posts module with the "title" and "body" fields. So, let’s follow the below steps.
Step for Angular 18 CRUD with Node JS Express MySQL Database
- Step 1: Create Angular 18 Project
- Step 2: Install Bootstrap
- Step 3: Create Post Module
- Step 4: Create Component For Module
- Step 5: Create Routes
- Step 6: Create Interface
- Step 7: Create Service
- Step 8: Update Component Logic and Template
- Step 9: export provideHttpClient()
- Step 10: Create REST API using Node JS and MySQL
- Run Node JS App
- Run Angular App
Now, let's follow the below step to create crud operations with angular 18.
Step 1: Create Angular 18 Project
You can easily create your angular app using below command:
ng new my-new-app
Step 2: Install Bootstrap
now, we will install bootstrap for our crud application, so let's run bellow command and import it to css file.
npm install bootstrap --save
Now after successfully run above command. let's import it in angular.json file.
....
"styles": [
"node_modules/bootstrap/dist/css/bootstrap.min.css",
"src/styles.css"
],
.....
Step 3: Create Post Module
After creating successfully app, we need to create post module using angular cli command. angular provide command to create module with routing in angular application. so let's run bellow command to create post module:
ng generate module post
run successfully command, it will create files as like bellow path:
src/app/post/post.module.ts
Step 4: Create Component For Module
Now we will add new component to our post module using bellow command, so let's create index, view, create and edit component for admin module:
ng generate component post/index
ng generate component post/view
ng generate component post/create
ng generate component post/edit
run successfully command, it will create folder with files as like bellow path:
src/app/post/index/*
src/app/post/view/*
src/app/post/create/*
src/app/post/edit/*
Step 5: Create Routes
In this step, we will simply create route for index, create, edit and view using generated new component. so we have to update our app.routes.ts module file as like bellow code:
src/app/app.routes.ts
import { Routes } from '@angular/router';
import { IndexComponent } from './post/index/index.component';
import { ViewComponent } from './post/view/view.component';
import { CreateComponent } from './post/create/create.component';
import { EditComponent } from './post/edit/edit.component';
export const routes: Routes = [
{ path: 'post', redirectTo: 'post/index', pathMatch: 'full'},
{ path: 'post/index', component: IndexComponent },
{ path: 'post/:postId/view', component: ViewComponent },
{ path: 'post/create', component: CreateComponent },
{ path: 'post/:postId/edit', component: EditComponent }
];
Step 6: Create Interface
in this step, we will create interface using angular command for post module. we will use post interface with Observable. so let's create interface with bellow code.
ng generate interface post/post
src/app/post/post.ts
export interface Post {
id: number;
title: string;
body: string;
}
Step 7: Create Service
Here, we will create post service file and we will write and call all web services. we will create getAll(), create(), find(), update() and delete().
we are using http://localhost:8000 web site api for now. in step 10, we are creating a node js app with posts REST API.
Now, let's create post service and put all code for web service method.
ng generate service post/post
src/app/post/post.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { Post } from './post';
@Injectable({
providedIn: 'root'
})
export class PostService {
private apiURL = "http://localhost:3000";
/*------------------------------------------
--------------------------------------------
Http Header Options
--------------------------------------------
--------------------------------------------*/
httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
}
/*------------------------------------------
--------------------------------------------
Created constructor
--------------------------------------------
--------------------------------------------*/
constructor(private httpClient: HttpClient) { }
/**
* Write code on Method
*
* @return response()
*/
getAll(): Observable {
return this.httpClient.get(this.apiURL + '/posts/')
.pipe(
catchError(this.errorHandler)
)
}
/**
* Write code on Method
*
* @return response()
*/
create(post:Post): Observable {
return this.httpClient.post(this.apiURL + '/posts/create', JSON.stringify(post), this.httpOptions)
.pipe(
catchError(this.errorHandler)
)
}
/**
* Write code on Method
*
* @return response()
*/
find(id:number): Observable {
return this.httpClient.get(this.apiURL + '/posts/' + id)
.pipe(
catchError(this.errorHandler)
)
}
/**
* Write code on Method
*
* @return response()
*/
update(id:number, post:Post): Observable {
return this.httpClient.put(this.apiURL + '/posts/' + id, JSON.stringify(post), this.httpOptions)
.pipe(
catchError(this.errorHandler)
)
}
/**
* Write code on Method
*
* @return response()
*/
delete(id:number){
return this.httpClient.delete(this.apiURL + '/posts/' + id, this.httpOptions)
.pipe(
catchError(this.errorHandler)
)
}
/**
* Write code on Method
*
* @return response()
*/
errorHandler(error:any) {
let errorMessage = '';
if(error.error instanceof ErrorEvent) {
errorMessage = error.error.message;
} else {
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
return throwError(errorMessage);
}
}
Step 8: Update Component Logic and Template
Now in this step, we will work on our created component for crud application. we create four component for our crud application. now we will go one by one for creating list page, create page, edit page and view page.
so, let's see one by one:
1) List Page Template and Component
now, here we will work on post index component. we will call post service and display it with create, edit, delete and view button. so let's update it.
src/app/post/index/index.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule, Router } from '@angular/router';
import { PostService } from '../post.service';
import { Post } from '../post';
@Component({
selector: 'app-index',
standalone: true,
imports: [CommonModule, RouterModule],
templateUrl: './index.component.html',
styleUrl: './index.component.css'
})
export class IndexComponent {
posts: Post[] = [];
/*------------------------------------------
--------------------------------------------
Created constructor
--------------------------------------------
--------------------------------------------*/
constructor(public postService: PostService, private router: Router) { }
/**
* Write code on Method
*
* @return response()
*/
ngOnInit(): void {
console.log(this.router.url);
console.log( window.location.href);
this.postService.getAll().subscribe((data: Post[])=>{
this.posts = data;
console.log(this.posts);
})
}
/**
* Write code on Method
*
* @return response()
*/
deletePost(id:number){
this.postService.delete(id).subscribe(res => {
this.posts = this.posts.filter(item => item.id !== id);
console.log('Post deleted successfully!');
})
}
}
src/app/post/index/index.component.html
<div class="container">
<h1>Angular 18 CRUD with Node JS MySQL Example - ItSolutionStuff.com</h1>
<a href="#" routerLink="/post/create/" class="btn btn-success">Create New Post</a>
<table class="table table-striped table-bordered">
<thead>
<tr>
<th>ID</th>
<th>Title</th>
<th>Body</th>
<th width="250px">Action</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let post of posts">
<td>{{ post.id }}</td>
<td>{{ post.title }}</td>
<td>{{ post.body }}</td>
<td>
<a href="#" [routerLink]="['/post/', post.id, 'view']" class="btn btn-info">View</a>
<a href="#" [routerLink]="['/post/', post.id, 'edit']" class="btn btn-primary">Edit</a>
<button type="button" (click)="deletePost(post.id)" class="btn btn-danger">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
You will see preview as like bellow:
2) Create Page Template and Component
now here, we will use reactive form store data into server using web services. so let's update it.
src/app/post/create/create.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PostService } from '../post.service';
import { Router } from '@angular/router';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-create',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
templateUrl: './create.component.html',
styleUrl: './create.component.css'
})
export class CreateComponent {
form!: FormGroup;
/*------------------------------------------
--------------------------------------------
Created constructor
--------------------------------------------
--------------------------------------------*/
constructor(
public postService: PostService,
private router: Router
) { }
/**
* Write code on Method
*
* @return response()
*/
ngOnInit(): void {
this.form = new FormGroup({
title: new FormControl('', [Validators.required]),
body: new FormControl('', Validators.required)
});
}
/**
* Write code on Method
*
* @return response()
*/
get f(){
return this.form.controls;
}
/**
* Write code on Method
*
* @return response()
*/
submit(){
console.log(this.form.value);
this.postService.create(this.form.value).subscribe((res:any) => {
console.log('Post created successfully!');
this.router.navigateByUrl('post/index');
})
}
}
src/app/post/create/create.component.html
<div class="container">
<h1>Create New Post</h1>
<a href="#" routerLink="/post/index" class="btn btn-primary">Back</a>
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group">
<label for="title">Title:</label>
<input
formControlName="title"
id="title"
type="text"
class="form-control">
<div *ngIf="f['title'].touched & f['title'].invalid" class="alert alert-danger">
<div *ngIf="f['title'].errors & f['title'].errors['required']">
Title is required.
</div>
</div>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea
formControlName="body"
id="body"
type="text"
class="form-control">
</textarea>
<div *ngIf="f['body'].touched & f['body'].invalid" class="alert alert-danger">
<div *ngIf="f['body'].errors & f['body'].errors['required']">
Body is required.<
/div>
</div>
</div>
<button class="btn btn-primary" type="submit" [disabled]="!form.valid">Submit</button>
</form>
</div>
You will see preview as like bellow:
3) Edit Page Template and Component
now here, we will use reactive form store data into server using web services for update post information. so let's update it.
src/app/post/edit/edit.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { PostService } from '../post.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Post } from '../post';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';
@Component({
selector: 'app-edit',
standalone: true,
imports: [CommonModule, ReactiveFormsModule],
templateUrl: './edit.component.html',
styleUrl: './edit.component.css'
})
export class EditComponent {
id!: number;
post!: Post;
form!: FormGroup;
/*------------------------------------------
--------------------------------------------
Created constructor
--------------------------------------------
--------------------------------------------*/
constructor(
public postService: PostService,
private route: ActivatedRoute,
private router: Router
) { }
/**
* Write code on Method
*
* @return response()
*/
ngOnInit(): void {
this.id = this.route.snapshot.params['postId'];
this.postService.find(this.id).subscribe((data: Post)=>{
this.post = data;
});
this.form = new FormGroup({
title: new FormControl('', [Validators.required]),
body: new FormControl('', Validators.required)
});
}
/**
* Write code on Method
*
* @return response()
*/
get f(){
return this.form.controls;
}
/**
* Write code on Method
*
* @return response()
*/
submit(){
console.log(this.form.value);
this.postService.update(this.id, this.form.value).subscribe((res:any) => {
console.log('Post updated successfully!');
this.router.navigateByUrl('post/index');
})
}
}
src/app/post/edit/edit.component.html
<div class="container">
<h1>Update Post</h1>
<a href="#" routerLink="/post/index" class="btn btn-primary">Back</a>
<form [formGroup]="form" (ngSubmit)="submit()">
<div class="form-group">
<label for="title">Title:</label>
<input
formControlName="title"
id="title"
type="text"
[(ngModel)]="post.title"
class="form-control">
<div *ngIf="f['title'].touched & f['title'].invalid" class="alert alert-danger">
<div *ngIf="f['title'].errors & f['title'].errors['required']">
Title is required.
</div>
</div>
</div>
<div class="form-group">
<label for="body">Body</label>
<textarea
formControlName="body"
id="body"
type="text"
[(ngModel)]="post.body"
class="form-control">
</textarea>
<div *ngIf="f['body'].touched & f['body'].invalid" class="alert alert-danger">
<div *ngIf="f['body'].errors & f['body'].errors['required']">
Body is required.
</div>
</div>
</div>
<button class="btn btn-primary" type="submit" [disabled]="!form.valid">Update</button>
</form>
</div>
You will see preview as like bellow:
4) Detail Page Template and Component
now here, we will display data into server using web services for update post information. so let's update it.
src/app/post/view/view.component.ts
import { Component } from '@angular/core';
import { PostService } from '../post.service';
import { ActivatedRoute, Router } from '@angular/router';
import { Post } from '../post';
@Component({
selector: 'app-view',
standalone: true,
imports: [],
templateUrl: './view.component.html',
styleUrl: './view.component.css'
})
export class ViewComponent {
id!: number;
post!: Post;
/*------------------------------------------
--------------------------------------------
Created constructor
--------------------------------------------
--------------------------------------------*/
constructor(
public postService: PostService,
private route: ActivatedRoute,
private router: Router
) { }
/**
* Write code on Method
*
* @return response()
*/
ngOnInit(): void {
this.id = this.route.snapshot.params['postId'];
this.postService.find(this.id).subscribe((data: Post)=>{
this.post = data;
});
}
}
src/app/post/view/view.component.html
<div class="container">
<h1>View Post</h1>
<a href="#" routerLink="/post/index" class="btn btn-primary">Back</a>
<div>
<strong>ID:</strong>
<p>{{ post.id }}</p>
</div>
<div>
<strong>Title:</strong>
<p>{{ post.title }}</p>
</div>
<div>
<strong>Body:</strong>
<p>{{ post.body }}</p>
</div>
</div>
You will see preview as like bellow:
Now let's update app html view:
src/app/app.component.html
<router-outlet></router-outlet>
Step 9: export provideHttpClient()
In this step, we need to export provideHttpClient() to app.config.ts file. so let's import it as like bellow:
src/app/app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideAnimations } from '@angular/platform-browser/animations';
import { provideHttpClient } from '@angular/common/http';
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes), provideAnimations(), provideHttpClient()]
};
Step 10: Create REST API using Node JS and MySQL
In last step, we will create posts rest API using node js, express and mysql.
Setting up MySQL database:
Before proceed to this step, make sure you have installed MySQL in your system.
Create a MySQL database and a table for storing posts:
CREATE DATABASE IF NOT EXISTS node_express_mysql;
USE node_express_mysql;
CREATE TABLE IF NOT EXISTS posts (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
body TEXT NOT NULL
);
Execute the below command to create new node js app:
mkdir node-express-mysql-rest-api
cd node-express-mysql-rest-api
Then run the below command to setup node js:
npm init -y
Next, 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 mysql body-parser
npm install cors
Next, Create an index.js file and set up the Express server with routes for CRUD operations:
node-express-mysql-rest-api/index.js
const express = require('express');
const bodyParser = require('body-parser');
const mysql = require('mysql');
const cors = require('cors');
const app = express();
const port = 3000;
/* MySQL Connection */
const db = mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'root',
database: 'node_express_mysql'
});
/* Connect to MySQL */
db.connect(err => {
if (err) {
throw err;
}
console.log('Connected to MySQL');
});
/* Middleware */
app.use(bodyParser.json());
app.use(cors());
/* Routes */
/* List all posts */
app.get('/posts', (req, res) => {
db.query('SELECT * FROM posts', (err, results) => {
if (err) {
res.status(500).send('Error fetching posts');
return;
}
res.json(results);
});
});
/* Create a new post */
app.post('/posts/create', (req, res) => {
const { title, body } = req.body;
db.query('INSERT INTO posts (title, body) VALUES (?, ?)', [title, body], (err, result) => {
if (err) {
res.status(500).send('Error creating post');
return;
}
const postId = result.insertId;
db.query('SELECT * FROM posts WHERE id = ?', postId, (err, result) => {
if (err) {
res.status(500).send('Error fetching created post');
return;
}
res.status(201).json(result[0]);
});
});
});
/* Get a specific post */
app.get('/posts/:id', (req, res) => {
const postId = req.params.id;
db.query('SELECT * FROM posts WHERE id = ?', postId, (err, result) => {
if (err) {
res.status(500).send('Error fetching post');
return;
}
if (result.length === 0) {
res.status(404).send('Post not found');
return;
}
res.json(result[0]);
});
});
/* Update a post */
app.put('/posts/:id', (req, res) => {
const postId = req.params.id;
const { title, body } = req.body;
db.query('UPDATE posts SET title = ?, body = ? WHERE id = ?', [title, body, postId], err => {
if (err) {
res.status(500).send('Error updating post');
return;
}
db.query('SELECT * FROM posts WHERE id = ?', postId, (err, result) => {
if (err) {
res.status(500).send('Error fetching updated post');
return;
}
res.json(result[0]);
});
});
});
/* Delete a post */
app.delete('/posts/:id', (req, res) => {
const postId = req.params.id;
db.query('DELETE FROM posts WHERE id = ?', postId, err => {
if (err) {
res.status(500).send('Error deleting post');
return;
}
res.status(200).json({ msg: 'Post deleted successfully' });
});
});
/* Start server */
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
Run Node JS App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Node.js app:
node index.js
Now, it's enable http://localhost:3000 URL to access created REST API.
Run Angular App:
All the required steps have been done, now you have to type the given below command and hit enter to run the Angular app:
ng serve
Now, Go to your web browser, type the given URL and view the app output:
http://localhost:4200/post
Home Page:
Create Page:
Edit Page:
Detail Page:
I hope it can help you...
Hardik Savani
I'm a full-stack developer, entrepreneur and owner of ItSolutionstuff.com. I live in India and I love to write tutorials and tips that can help to other artisan. I am a big fan of PHP, Laravel, Angular, Vue, Node, Javascript, JQuery, Codeigniter and Bootstrap from the early stage. I believe in Hardworking and Consistency.
We are Recommending you
- Angular 18 Add Social Media Share Buttons Example
- How to Create Interface in Angular 18?
- Angular 18 Async Pipe Example Tutorial
- Angular 18 @for and @empty For Loop Example
- Angular 18 Conditional Statements @if, @else if, and @else Example
- How to Get Current Route in Angular 18?
- Angular 18 Install Font Awesome Icons Example
- How to Integrate Google Maps in Angular 18?
- Angular 18 Login with Google Gmail Account Example
- Angular 18 Pagination with NGX Pagination Example
- Angular 18 Multiple Image Upload Example Tutorial
- Angular 18 Image Upload with Preview Example
- How to Add Bootstrap 5 in Angular 18 Application?