Monday 27 May 2024

PHP 8 MySQL Project on Online Examination System


The advent of digital technologies has revolutionized various aspects of education, including examination systems. Traditional paper-based exams are increasingly being replaced by online examination systems, which offer numerous advantages such as efficiency, accuracy, and accessibility. In this article, we will explore the development of an online examination system using PHP 8 and MySQL, focusing on the features for three types of users: Admin, Sub User, and Student.

PHP 8 MySQL Project on Online Examination System




Key Features of the Online Examination System


Our online examination system is designed to cater to the needs of different users within the educational ecosystem. The system includes comprehensive features for admins, sub-users (such as teachers or moderators), and students, ensuring a seamless and efficient examination process.

Admin User Features


The Admin user has the highest level of control within the system, responsible for managing classes, subjects, students, exams, and sub-users. Here are the detailed functionalities available to the Admin:

  • Class Management: Admins can add, edit, disable, or enable class data, allowing them to organize students into different educational levels or groups.
  • Subject Management: Admins can manage subject data, including adding new subjects, editing existing ones, and enabling or disabling subjects as needed.
  • Subject Assignment: Admins can assign subjects to specific classes, edit these assignments, and delete any outdated or incorrect assignments.
  • Student Management: Admins can handle student data comprehensively by adding new students, editing details, and enabling or disabling students' statuses.
  • Student Class Assignment: Admins can assign students to classes, edit these assignments, and control the activation status of these assignments.
  • Exam Management: Admins can create, edit, and delete exam data, ensuring that the examination schedules and details are up-to-date.
  • Exam Subject Management: Admins can add, edit, and delete exam subject data, allowing for precise control over which subjects are included in each exam.
  • Exam Question Management: Admins can manage exam questions, including adding new questions, editing existing ones, and removing outdated questions.
  • Sub User Management: Admins can manage sub-user data by adding, editing, disabling, or enabling sub-user accounts.




Sub User Features


Sub-users, such as teachers or moderators, have access to functionalities that allow them to manage exams and related data. Their capabilities include:

  • Exam Management: Sub-users can add, edit, and delete exam data, assisting in the organization and scheduling of exams.
  • Exam Subject Management: Sub-users can manage the subjects related to each exam, ensuring that all necessary subjects are included.
  • Exam Question Management: Sub-users can add, edit, and delete exam questions, contributing to the creation of comprehensive question banks.

Student User Features


Students are the primary users of the online examination system. Their experience is designed to be straightforward and user-friendly, providing the following features:

  • Login: Students can securely log in to the system using their credentials.
  • View Exam Details: Students can view details of upcoming exams, including subjects, schedules, and instructions.
  • Participate in Exams: Students can take part in exams directly through the system, answering questions and submitting their responses online.
  • View Exam Results: After completing an exam, students can view their results, including scores and feedback, if provided.

Developing the System with PHP 8 and MySQL


PHP 8 brings numerous improvements and new features to the table, making it an excellent choice for developing robust web applications. Coupled with MySQL, a powerful relational database management system, developers can create efficient and scalable online examination systems.

Setting Up the Environment


To start, ensure you have a web server (such as Apache or Nginx) and a MySQL server installed on your development machine. You will also need PHP 8 installed, along with necessary extensions like PDO for database interactions.

Database Design


Designing the database is a critical step. The database should include tables for users (admin, sub-users, and students), classes, subjects, exams, exam subjects, and questions. Each table should be normalized to reduce redundancy and ensure data integrity.

Implementing the Admin Features


For the admin features, create CRUD (Create, Read, Update, Delete) operations for classes, subjects, students, exams, and sub-users. Use PHP to handle server-side logic and MySQL to store and retrieve data. Implement user authentication and role-based access control to ensure only authorized users can perform certain actions.

Developing the Sub User and Student Interfaces


For sub-users, implement interfaces that allow them to manage exams and questions. Ensure they have a restricted set of permissions compared to admins. For students, develop a user-friendly interface where they can log in, view exams, participate in them, and see their results. Use AJAX for smooth interactions and real-time updates.

Security Considerations


Security is paramount in an online examination system. Implement robust authentication and authorization mechanisms, protect against SQL injection by using prepared statements, and ensure data is transmitted over HTTPS to prevent eavesdropping.





Conclusion


Developing an online examination system with PHP 8 and MySQL involves careful planning and execution. By providing distinct features for admins, sub-users, and students, the system ensures a smooth and efficient examination process. With PHP 8's new features and MySQL's reliability, this system can handle the demands of modern educational institutions, offering a scalable and secure solution for online examinations.





Sunday 5 May 2024

Building a Real-Time Chat Application Project in Node JS with MongoDB


In today's fast-paced digital world, real-time communication has become a necessity for many applications. Whether it's collaborating with team members, providing customer support, or simply connecting friends and family, the demand for real-time chat applications is ever-growing. In this article, we'll delve into the process of building a real-time chat application using Node.js and MongoDB, two powerful technologies that complement each other seamlessly.


Building a Real-Time Chat Application Project in Node JS with MongoDB




Why Node.js and MongoDB?


Node.js is a popular runtime environment for building scalable and efficient server-side applications. Its event-driven architecture and non-blocking I/O make it an excellent choice for real-time applications such as chat. MongoDB, on the other hand, is a flexible and scalable NoSQL database that stores data in JSON-like documents, making it well-suited for handling the unstructured data typically found in chat applications.





Feature of Chat Application


1. User Registration


User registration allows individuals to create an account on your chat application. To implement this feature:

  • Create User Schema: Use Mongoose to define a schema for users. Include fields such as username, email, password (hashed using bcrypt), profile picture, and any other relevant information.
  • Registration Endpoint: Set up an endpoint in Express to handle user registration requests. Validate incoming data using Joi, hash the password using bcrypt, and then save the user data to MongoDB using Mongoose.
  • User Authentication: Upon successful registration, generate a JWT token using jsonwebtoken and send it back to the client. This token will be used for subsequent authentication.

2. User Login using JSON Web Token


User login allows registered users to authenticate themselves and access the chat application. Here's how to implement it:

  • Login Endpoint: Create an endpoint to handle user login requests. Validate the user's credentials (username/email and password), compare the hashed password with the stored hash in the database, and if they match, generate a JWT token and send it back to the client.
  • Token Storage: Store the JWT token securely on the client-side (e.g., in local storage or cookies) to be sent along with subsequent requests for authentication.
  • Middleware for Authentication: Create a middleware function in Express to verify the JWT token on protected routes. If the token is valid, allow access to the requested resource; otherwise, return a 401 Unauthorized error.

3. Edit User Profile Data with Image Upload


This feature enables users to update their profile information, including uploading a new profile picture. Here's how to implement it:

  • Profile Update Endpoint: Create an endpoint to handle profile update requests. Allow users to update fields such as username, email, bio, etc. For profile picture updates, use Multer to handle file uploads and save the image to a designated folder.
  • Link Profile Picture to User: Store the file path or URL of the uploaded profile picture in the user document in MongoDB.
  • Secure File Uploads: Implement validation and security measures to prevent unauthorized file uploads and ensure that only allowed file types and sizes are accepted.

4. Search User


This feature allows users to search for other users within the chat application. Here's how to implement it:

  • Search Endpoint: Create an endpoint to handle user search queries. Accept search parameters such as username or email and query the user database in MongoDB to find matching users.
  • Return Search Results: Send the list of matching users back to the client as a response.

5. Display Search Request Notification


When a user receives a search request, they should be notified. Here's how to implement it:

  • Real-Time Notifications: Use Socket.io to emit a notification event to the recipient user when they receive a search request.
  • Display Notification: Implement client-side logic to display the notification to the user in real-time, such as using toast notifications or updating the UI dynamically.

6. Accept Search Request


This feature allows users to accept incoming search requests. Here's how to implement it:

  • Accept Request Endpoint: Create an endpoint to handle requests to accept incoming search requests. Update the status of the search request in the database to indicate acceptance.
  • Real-Time Updates: Emit a notification event to the sender of the search request to inform them that their request has been accepted.

7. List Accepted Search Request User


Users should be able to see a list of users who have accepted their search requests. Here's how to implement it:

  • List Accepted Requests Endpoint: Create an endpoint to retrieve a list of users who have accepted the current user's search requests.
  • Return Accepted Users: Send the list of accepted users back to the client as a response.

8. Start Chat with other User


This feature enables users to initiate a chat with other users. Here's how to implement it:

  • Chat Initiation Endpoint: Create an endpoint to handle requests to start a chat with another user. Store the chat information in the database, including the participants and any initial messages.
  • Real-Time Chat: Use Socket.io to establish real-time communication between users in the chat. Emit events for sending and receiving messages, typing indicators, etc.

9. Display User Online Offline Status


Users should be able to see the online/offline status of other users. Here's how to implement it:

  • Real-Time Status Updates: Use Socket.io to emit events for updating the online/offline status of users in real-time.
  • Update User Status: Implement logic on the server-side to update the user's status in the database based on their activity (e.g., logging in/out).

By implementing these features, you can create a comprehensive and user-friendly chat application that provides a seamless communication experience for your users.





Setting Up the Environment


Before we start building our chat application, let's ensure we have Node.js and MongoDB installed on our system. Once installed, we can create a new directory for our project and initialize a new Node.js project using npm.

	
		mkdir node-chat
		cd node-chat
	

Next, let's install the necessary dependencies:

1. Express


	
		npm install express
	

Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. It simplifies the process of building web servers and handling HTTP requests by providing a simple and intuitive API.

In our chat application, we use Express to:

  • Set up our server and define routes for handling HTTP requests.
  • Serve static files such as HTML, CSS, and client-side JavaScript.
  • Implement middleware for parsing incoming request bodies and handling errors.

2. Multer


	
		npm install multer
	

Multer is a middleware for handling multipart/form-data, which is primarily used for uploading files. While our chat application may not require file uploads, it's a good practice to include Multer for handling any future enhancements that may involve file uploads.

3. Mongoose


	
		npm install mongoose
	

Mongoose is an elegant MongoDB object modeling tool designed to work in an asynchronous environment. It provides a straightforward schema-based solution to model application data, validate incoming data, and perform CRUD operations on MongoDB databases.

In our chat application, Mongoose helps us:

  • Define schemas for our MongoDB documents, such as user profiles and chat messages.
  • Create models based on these schemas to interact with the MongoDB database.
  • Perform data validation and define relationships between different types of data.

4. Joi


	
		npm install joi
	

Joi is a powerful schema description language and data validator for JavaScript. It allows us to define schemas for the data our application expects to receive, validate incoming data against these schemas, and provide helpful error messages if validation fails.

In our chat application, Joi can be used to:

  • Validate incoming requests to ensure that they contain the expected data in the correct format.
  • Sanitize and coerce incoming data to ensure consistency and security.
  • Handle validation errors gracefully and provide meaningful feedback to the user.

5. Bcrypt


	
		npm install bcrypt
	

Bcrypt is a widely-used library for hashing passwords in Node.js applications. It provides a secure way to hash passwords before storing them in the database, making it difficult for attackers to reverse-engineer passwords even if they gain access to the database.

In our chat application, Bcrypt is essential for:

  • Hashing user passwords before storing them in the database to protect user accounts from unauthorized access.
  • Comparing hashed passwords during the authentication process to verify the identity of users.

6. Jsonwebtoken


	
		npm install jsonwebtoken
	

Jsonwebtoken is a library for generating and verifying JSON Web Tokens (JWTs) in Node.js applications. JWTs are a compact and self-contained way of representing claims between parties, making them ideal for authentication and information exchange.

In our chat application, Jsonwebtoken is used for:

  • Generating JWTs when users successfully authenticate with the server.
  • Verifying JWTs when users make requests to protected routes, ensuring that they are authorized to access the requested resources.

By leveraging these libraries in our chat application, we can ensure that our application is secure, efficient, and scalable, while also providing a seamless user experience.

Conclusion


In this article, we've covered the process of building a real-time chat application using Node.js and MongoDB. By leveraging the power of Socket.io for real-time communication and MongoDB for data storage, we've created a scalable and efficient chat application that can handle a large number of users simultaneously. With some additional features and enhancements, you can further customize and extend this application to meet your specific requirements.

Beyond its practical applications, this Node.js chat application project can serve as a valuable educational resource for students and by incorporating this Node.js chat application project into educational curricula or as part of self-directed learning, students can gain practical experience in building real-world applications while reinforcing core concepts in web development, software engineering, and computer science. Whether used as a standalone project or as part of a larger curriculum, this project offers a valuable opportunity for hands-on learning and skill development.





Friday 8 March 2024

Nodejs Drag & Drop Multiple File Upload using Multer


Introduction:


In today's digital world, file uploading is a common functionality for web applications. Node.js, with its asynchronous and event-driven architecture, offers an excellent platform for handling file uploads efficiently. Multer, a middleware for Express.js, simplifies the process of handling multipart/form-data, making it perfect for handling multiple file uploads.

In this tutorial, we will explore how to implement drag and drop multiple file uploads using Node.js and Multer, ensuring the content is optimized for search engines.


Node.js Drag & Drop Multiple File Upload using Multer


Table of Contents:


  1. Setting up the Project Environment
  2. Installing Dependencies
  3. Configuring Multer Middleware
  4. Creating the Frontend Interface
  5. Implementing Drag and Drop Functionality
  6. Handling File Uploads on the Server
  7. Run Application
  8. Conclusion

1. Setting up the Project Environment:


Before diving into the code, let's ensure we have Node.js installed on our system. If not, download and install it from the official Node.js website.

	
	mkdir drag-drop
	cd drag-drop
	

2. Installing Dependencies:


Initialize a new Node.js project and install the required dependencies using npm:

	
	npm init -y
	npm install express multer
	

3. Configuring Multer Middleware:


Create an Express.js server under server.js and configure Multer middleware to handle file uploads:

server.js
	
	const express = require('express');
	const multer = require('multer');
	const path = require('path');
	const app = express();
	const PORT = 3000;
	app.use(express.static(__dirname));

	// Set up Multer storage
	const storage = multer.diskStorage({
		destination : function(request, file, callback) {
			callback(null, 'uploads/');
		},
		filename : function(request, file, callback) {
			callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
		}
	});

	// Initialize Multer upload
	const upload = multer({storage : storage});
	
	app.get('/upload', async (request, response) => {
		response.sendFile(__dirname + '/upload.html');
	});
	
	app.listen(PORT, () => {
		console.log(`Server is running on port ${PORT}`);
	});
	

4. Creating the Frontend Interface:


Design a simple HTML page with name upload.html file with drag and drop functionality for uploading files:

upload.html
	
	<!doctype html>
	<html lang="en">
		<head>
			<!-- Required meta tags -->
			<meta charset="utf-8">
			<meta name="viewport" content="width=device-width, initial-scale=1">

			<!-- Bootstrap CSS -->
			<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

			<title>Drag and Drop File Upload</title>
		</head>
		<body>
			
			<div class="container">
				<h1 class="text-center mb-5 mt-5"><b>Drag and Drop File Upload in Node.js</b></h1>

				<div id="drop_zone">
					<p>Drag and drop files here</p>
				</div>
				<br />
				<div class="card mb-5">
					<div class="card-header">
						<div class="row">
							<div class="col col-6">Uploaded File</div>
							<div class="col col-6"></div>
						</div>
					</div>
					<div id="uploadedImage" class="card-body">

					</div>
				</div>
			</div>
			<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
		</body>
	</html>

	<style>
	#drop_zone {
			width: 100%;
			min-height: 200px;
			border: 2px dashed #ccc;
			border-radius: 10px;
			padding: 20px;
			box-sizing: border-box;
			display: flex;
			justify-content: center;
			align-items: center;
			flex-direction: column;
		}
		#drop_zone.hover {
			background-color: #f0f0f0;
		}
	</style>
	

5. Implementing Drag and Drop Functionality:


Write JavaScript code in uplode.html file to handle drag and drop functionality:

upload.html
	
	<script>

	var dropZone = document.getElementById('drop_zone');

	dropZone.addEventListener('dragover', (event) => {
		event.preventDefault();
		dropZone.classList.add('hover');
	});

	dropZone.addEventListener('dragleave', (event) => {
		event.preventDefault();
		dropZone.classList.remove('hover');
	});

	dropZone.addEventListener('drop', (event) => {
		event.preventDefault();
		dropZone.classList.remove('hover');
		var files = event.dataTransfer.files;
		handlesFiles(files);
	});

	function handlesFiles(files){
		for(var count = 0; count < files.length; count++){
			var file = files[count];
			uploadFile(file);
		}
	}

	function uploadFile(file){
		var formData = new FormData();
		formData.append('file', file);
		fetch('/upload', {
			method : 'POST',
			body : formData
		})
		.then(response => response.json())
		.then(data => {
			const gallery = document.getElementById('uploadedImage');
			let html = `<img src="/uploads/${data.filename}" class="img-thumbnail" />`;
			gallery.innerHTML = gallery.innerHTML + html;
		});
	}

	</script>
	

6. Handling File Uploads on the Server:


Now in server.js, we have to handle file uploads on the server-side using Express.js:

server.js
	
	app.post('/upload', upload.single('file'), (request, response) => {
		response.json({ filename : request.file.filename });
	});
	

7. Run Application


After writing all above code, for run this node application in browser, we have to start node server, so we have goes to terminal window, and there we have to run node server.js command which will start node development server.

And at browser, we have to open http://localhost:3000 url, then it will open this Node Drag and Drop application in browser.

8. Conclusion:


Congratulations! You've successfully implemented drag and drop multiple file uploads using Node.js and Multer. This tutorial covered the setup of the project environment, installation of dependencies, configuration of Multer middleware, creation of the frontend interface, implementation of drag and drop functionality, handling file uploads on the server, and displaying upload progress.

Complete Source Code


server.js
	
	const express = require('express');
	const multer = require('multer');
	const path = require('path');
	const app = express();
	const PORT = 3000;
	app.use(express.static(__dirname));

	// Set up Multer storage
	const storage = multer.diskStorage({
		destination : function(request, file, callback) {
			callback(null, 'uploads/');
		},
		filename : function(request, file, callback) {
			callback(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
		}
	});

	// Initialize Multer upload
	const upload = multer({storage : storage});

	app.get('/upload', async (request, response) => {
		response.sendFile(__dirname + '/upload.html');
	});

	app.post('/upload', upload.single('file'), (request, response) => {
		response.json({ filename : request.file.filename });
	});

	app.listen(PORT, () => {
		console.log(`Server is running on port ${PORT}`);
	});
	

upload.html
	
	<!doctype html>
	<html lang="en">
		<head>
			<!-- Required meta tags -->
			<meta charset="utf-8">
			<meta name="viewport" content="width=device-width, initial-scale=1">

			<!-- Bootstrap CSS -->
			<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

			<title>Drag and Drop File Upload</title>
		</head>
		<body>
			
			<div class="container">
				<h1 class="text-center mb-5 mt-5"><b>Drag and Drop File Upload in Node.js</b></h1>

				<div id="drop_zone">
					<p>Drag and drop files here</p>
				</div>
				<br />
				<div class="card mb-5">
					<div class="card-header">
						<div class="row">
							<div class="col col-6">Uploaded File</div>
							<div class="col col-6"></div>
						</div>
					</div>
					<div id="uploadedImage" class="card-body">

					</div>
				</div>
			</div>
			<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
		</body>
	</html>

	<style>
	#drop_zone {
			width: 100%;
			min-height: 200px;
			border: 2px dashed #ccc;
			border-radius: 10px;
			padding: 20px;
			box-sizing: border-box;
			display: flex;
			justify-content: center;
			align-items: center;
			flex-direction: column;
		}
		#drop_zone.hover {
			background-color: #f0f0f0;
		}
	</style>

	<script>

	var dropZone = document.getElementById('drop_zone');

	dropZone.addEventListener('dragover', (event) => {
		event.preventDefault();
		dropZone.classList.add('hover');
	});

	dropZone.addEventListener('dragleave', (event) => {
		event.preventDefault();
		dropZone.classList.remove('hover');
	});

	dropZone.addEventListener('drop', (event) => {
		event.preventDefault();
		dropZone.classList.remove('hover');
		var files = event.dataTransfer.files;
		handlesFiles(files);
	});

	function handlesFiles(files){
		for(var count = 0; count < files.length; count++){
			var file = files[count];
			uploadFile(file);
		}
	}

	function uploadFile(file){
		var formData = new FormData();
		formData.append('file', file);
		fetch('/upload', {
			method : 'POST',
			body : formData
		})
		.then(response => response.json())
		.then(data => {
			const gallery = document.getElementById('uploadedImage');
			let html = `<img src="/uploads/${data.filename}" class="img-thumbnail" />`;
			gallery.innerHTML = gallery.innerHTML + html;
		});
	}

	</script>
	

Wednesday 28 February 2024

Node.js CRUD Application with Mongo DB Database

Node.js CRUD Application with Mongo DB Database

Introduction:


In this tutorial, we'll walk through the process of building a CRUD (Create, Read, Update, Delete) application using Node.js and MongoDB. CRUD applications are fundamental in web development as they facilitate the basic operations for managing data in a database. We'll leverage the power of Node.js for the backend logic and MongoDB as the database to store our data. By the end of this tutorial, you'll have a solid understanding of how to create a fully functional CRUD application.





Prerequisites:


Before we begin, make sure you have the following installed on your system:

  1. Node.js
  2. MongoDB

Step 1: Setting Up Your Project:


Start by creating a new directory for your project and navigate into it using your terminal or command prompt.

	
	mkdir node-crud-app
	cd node-crud-app
	

Initialize a new Node.js project using npm.

	
	npm init -y
	

Step 2: Installing Dependencies:


Next, we need to install the necessary dependencies for our project. We'll use Express.js as our web framework and Mongoose as the MongoDB ODM (Object Data Modeling) library.

	
	npm install express mongoose body-parser
	

Step 3: Setting Up MongoDB:



In this tutorial, we have use Cloud Mongo DB Database. So in below video tutorial, you can find step by step guide for how to create Mongo DB Schema or Database in the Cloud.

Step 4: Creating the Server:


Create a file named server.js in your project directory and set up a basic Express server.

server.js
	
	const express = require('express');
	const bodyParser = require('body-parser');
	const mongoose = require('mongoose');

	const app = express();
	const PORT = 3000;

	app.use(bodyParser.json());

	app.use(express.static(__dirname));
	

Step 5: Connecting to MongoDB:


Add the code to connect your Node.js application to MongoDB using Mongoose.

server.js
	
	const express = require('express');
	const bodyParser = require('body-parser');
	const mongoose = require('mongoose');

	const app = express();
	const PORT = 3000;

	app.use(bodyParser.json());

	app.use(express.static(__dirname));

	mongoose.connect('mongodb+srv://johnsmith174:xxxxx@cluster0.8dbkdwt.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0');

	const connect = mongoose.connection;

	connect.on('error', console.error.bind(console, 'MongoDB connection error:'));

	connect.once('open', () => {
		console.log('Connected to MongoDB');
	});
	

Step 6: Creating Models:


Define a schema for your MongoDB documents and create models using Mongoose.

server.js
	
		const userSchema = new mongoose.Schema({
			name : String,
			email : String,
			age : Number
		});

		const User = mongoose.model('User', userSchema);
	

Step 7: Implementing CRUD Operations:


Now, let's implement the CRUD operations for our application - Create, Read, Update, and Delete.

Create Operation (POST):


The create operation involves adding new items to our database. We'll define a route to handle incoming POST requests to create new items.

So first we have to create one get route in server.js file for load HTML file in the browser.

server.js
	
		app.get('/', async (request, response) => {
			response.sendFile(__dirname + '/user.html');
		});
	

Next we have to create one user.html file and under this file, we have to create one button and when we have click on button then bootstrap modal must be pop up on web page and under modal we will make user form for insert data into MongoDB.

user.html
	
<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Bootstrap CSS -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

        <title>Build a CRUD App with Node.js and MongoDB</title>
    </head>
    <body>
        
        <div class="container">
            <h1 class="text-center mb-5 mt-5 text-danger"><b>Build a CRUD App with Node.js and MongoDB - Insert Data into MongoDB Database - 2</b></h1>
            <div class="card mb-5">
                <div class="card-header">
                    <div class="row">
                        <div class="col col-6">Sample Data</div>
                        <div class="col col-6">
                            <button type="button" class="btn btn-primary btn-sm float-end" onclick="makeModal('Add User', 'Add', 'insertData')">Add</button>
                        </div>
                    </div>
                </div>
                <div class="card-body">
                    <div class="table-responsive">
                        
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<div id="modalArea"></div>

<script>

var userModalElement;

function makeModal(title, button_value, callback)
{
    let html = `
    <div class="modal" tabindex="-1" id="userModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <form id="userform">
                    <div class="modal-header">
                        <h5 class="modal-title">${title}</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <div class="mb-3">
                            <label>Name</label>
                            <input type="text" name="name" id="name" class="form-control" />
                        </div>
                        <div class="mb-3">
                            <label>Email</label>
                            <input type="email" name="email" id="email" class="form-control" />
                        </div>
                        <div class="mb-3">
                            <label>Age</label>
                            <input type="number" name="age" id="age" class="form-control" />
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                        <button type="button" class="btn btn-primary" onclick="${callback}()">${button_value}</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
    `;

    document.querySelector('#modalArea').innerHTML = html;

    userModalElement = new bootstrap.Modal(document.getElementById('userModal'));

    userModalElement.show();
}

function insertData()
{
    let formElement = document.getElementById('userform');
    const formData = new FormData(formElement);
    // Convert formData to JSON
    const jsonData = {};
    formData.forEach((value, key) => {
        jsonData[key] = value;
    });
    // Make a POST request using Fetch API
    fetch('/users', {
        method : 'POST',
        body : JSON.stringify(jsonData),
        headers : {
            'Content-Type': 'application/json'
        }
    })
    .then(response => {
        return response.json();
    })
    .then(data => {
        userModalElement.hide();
        getData();
    });
}

</script>


Next we have goes to server.js file and here we have to create one POST route for handle form data for insert data into MongoDB.

server.js
	
	app.post('/users', async (request, response) => {
		const user = new User({
			name : request.body.name,
			email : request.body.email,
			age : request.body.age
		});
		const newItem = await user.save();
		response.status(201).json({scuccess:true});
	});
	

Read Operation (GET):


So for read data operation, first we have goest to user.html file and here we have to create one HTML table and then after we have goes to JavaScript code part, and here we have to create one getData() function which will send fetch data request to node application route and display on web page, and call this function into insertData() function, so when new data has been inserted then it will display last inserted data on web also.

user.html
	
	<!doctype html>
	<html lang="en">
		<head>
			<!-- Required meta tags -->
			<meta charset="utf-8">
			<meta name="viewport" content="width=device-width, initial-scale=1">

			<!-- Bootstrap CSS -->
			<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

			<title>Build a CRUD App with Node.js and MongoDB</title>
		</head>
		<body>
			
			<div class="container">
				<h1 class="text-center mb-5 mt-5 text-danger"><b>Build a CRUD App with Node.js and MongoDB - Insert Data into MongoDB Database - 2</b></h1>
				<div class="card mb-5">
					<div class="card-header">
						<div class="row">
							<div class="col col-6">Sample Data</div>
							<div class="col col-6">
								<button type="button" class="btn btn-primary btn-sm float-end" onclick="makeModal('Add User', 'Add', 'insertData')">Add</button>
							</div>
						</div>
					</div>
					<div class="card-body">
						<div class="table-responsive">
							<table class="table table-bordered table-striped">
								<thead>
									<tr>
										<th>Name</th>
										<th>Email</th>
										<th>Age</th>
										<th>Action</th>
									</tr>
								</thead>
								<tbody id="dataArea"></tbody>
							</table>
						</div>
					</div>
				</div>
			</div>
		</body>
	</html>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
	<div id="modalArea"></div>

	<script>

	var userModalElement;

	function makeModal(title, button_value, callback)
	{
		let html = `
		<div class="modal" tabindex="-1" id="userModal">
			<div class="modal-dialog">
				<div class="modal-content">
					<form id="userform">
						<div class="modal-header">
							<h5 class="modal-title">${title}</h5>
							<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
						</div>
						<div class="modal-body">
							<div class="mb-3">
								<label>Name</label>
								<input type="text" name="name" id="name" class="form-control" />
							</div>
							<div class="mb-3">
								<label>Email</label>
								<input type="email" name="email" id="email" class="form-control" />
							</div>
							<div class="mb-3">
								<label>Age</label>
								<input type="number" name="age" id="age" class="form-control" />
							</div>
						</div>
						<div class="modal-footer">
							<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
							<button type="button" class="btn btn-primary" onclick="${callback}()">${button_value}</button>
						</div>
					</form>
				</div>
			</div>
		</div>
		`;

		document.querySelector('#modalArea').innerHTML = html;

		userModalElement = new bootstrap.Modal(document.getElementById('userModal'));

		userModalElement.show();
	}

	function insertData()
	{
		let formElement = document.getElementById('userform');
		const formData = new FormData(formElement);
		// Convert formData to JSON
		const jsonData = {};
		formData.forEach((value, key) => {
			jsonData[key] = value;
		});
		// Make a POST request using Fetch API
		fetch('/users', {
			method : 'POST',
			body : JSON.stringify(jsonData),
			headers : {
				'Content-Type': 'application/json'
			}
		})
		.then(response => {
			return response.json();
		})
		.then(data => {
			userModalElement.hide();
			getData();
		});
	}

	getData();

	function getData(){
		fetch('/users')
		.then(response => {
			return response.json();
		})
		.then(data => {
			let html = '';
			if(data.length > 0){
				data.map((row) => {
					html += `
					<tr>
						<td>${row.name}</td>
						<td>${row.email}</td>
						<td>${row.age}</td>
						<td></td>
					</tr>
					`;
				});
			} else {
				html = '<tr><td colspan="4" class="text-center">No Data Found</td></tr>';
			}
			document.getElementById('dataArea').innerHTML = html;
		});
	}

	</script>
	

Next The read operation involves fetching existing items from the database. We'll define a route to handle incoming GET requests to retrieve items in server.js file.

server.js
	
		app.get('/users', async (request, response) => {
			const users = await User.find();
			response.status(200).json(users);
		});
	

Update Operation (PUT/PATCH):


For Update MongoDB data, first we have goes to user.html file and under this file, we have to create edit button in each of data, which will send get request for fetch single user data from MongoDB data and then after we have to create one editData() function which will be called when we have submit form data. So it will send PUT request to node crud application.

user.html
	
	<!doctype html>
	<html lang="en">
		<head>
			<!-- Required meta tags -->
			<meta charset="utf-8">
			<meta name="viewport" content="width=device-width, initial-scale=1">

			<!-- Bootstrap CSS -->
			<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

			<title>Build a CRUD App with Node.js and MongoDB</title>
		</head>
		<body>
			
			<div class="container">
				<h1 class="text-center mb-5 mt-5 text-danger"><b>Build a CRUD App with Node.js and MongoDB - Delete Data from MongoDB Database - 5</b></h1>
				<div class="card mb-5">
					<div class="card-header">
						<div class="row">
							<div class="col col-6">Sample Data</div>
							<div class="col col-6">
								<button type="button" class="btn btn-primary btn-sm float-end" onclick="makeModal('Add User', 'Add', 'insertData')">Add</button>
							</div>
						</div>
					</div>
					<div class="card-body">
						<div class="table-responsive">
							<table class="table table-bordered table-striped">
								<thead>
									<tr>
										<th>Name</th>
										<th>Email</th>
										<th>Age</th>
										<th>Action</th>
									</tr>
								</thead>
								<tbody id="dataArea"></tbody>
							</table>
						</div>
					</div>
				</div>
			</div>
		</body>
	</html>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
	<div id="modalArea"></div>

	<script>

	var userModalElement;

	function makeModal(title, button_value, callback)
	{
		let html = `
		<div class="modal" tabindex="-1" id="userModal">
			<div class="modal-dialog">
				<div class="modal-content">
					<form id="userform">
						<div class="modal-header">
							<h5 class="modal-title">${title}</h5>
							<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
						</div>
						<div class="modal-body">
							<div class="mb-3">
								<label>Name</label>
								<input type="text" name="name" id="name" class="form-control" />
							</div>
							<div class="mb-3">
								<label>Email</label>
								<input type="email" name="email" id="email" class="form-control" />
							</div>
							<div class="mb-3">
								<label>Age</label>
								<input type="number" name="age" id="age" class="form-control" />
							</div>
						</div>
						<div class="modal-footer">
							<input type="hidden" name="user_id" id="user_id" />
							<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
							<button type="button" class="btn btn-primary" onclick="${callback}()">${button_value}</button>
						</div>
					</form>
				</div>
			</div>
		</div>
		`;

		document.querySelector('#modalArea').innerHTML = html;

		userModalElement = new bootstrap.Modal(document.getElementById('userModal'));

		userModalElement.show();
	}

	function insertData()
	{
		let formElement = document.getElementById('userform');
		const formData = new FormData(formElement);
		// Convert formData to JSON
		const jsonData = {};
		formData.forEach((value, key) => {
			jsonData[key] = value;
		});
		// Make a POST request using Fetch API
		fetch('/users', {
			method : 'POST',
			body : JSON.stringify(jsonData),
			headers : {
				'Content-Type': 'application/json'
			}
		})
		.then(response => {
			return response.json();
		})
		.then(data => {
			userModalElement.hide();
			getData();
		});
	}

	getData();

	function getData(){
		fetch('/users')
		.then(response => {
			return response.json();
		})
		.then(data => {
			let html = '';
			if(data.length > 0){
				data.map((row) => {
					html += `
					<tr>
						<td>${row.name}</td>
						<td>${row.email}</td>
						<td>${row.age}</td>
						<td>
							<button type="button" class="btn btn-warning btn-sm" onclick="fetchSingleData('${row._id}')">Edit</button>
						</td>
					</tr>
					`;
				});
			} else {
				html = '<tr><td colspan="4" class="text-center">No Data Found</td></tr>';
			}
			document.getElementById('dataArea').innerHTML = html;
		});
	}

	function fetchSingleData(id){
		fetch(`/users/${id}`)
		.then(response => {
			return response.json();
		})
		.then(data => {
			makeModal('Edit User', 'Edit', 'editData');
			document.getElementById('name').value = data.name;
			document.getElementById('email').value = data.email;
			document.getElementById('age').value = data.age;
			document.getElementById('user_id').value = data._id;
		});
	}

	function editData(){
		let formElement = document.getElementById('userform');
		const formData = new FormData(formElement);
		let jsonData = {};
		formData.forEach((value, key) => { 
			jsonData[key] = value;
		});
		const userId = document.getElementById('user_id').value;
		fetch(`/users/${userId}`, {
			method : 'PUT',
			body : JSON.stringify(jsonData),
			headers : {
				'Content-Type': 'application/json'
			}
		})
		.then(response => {
			return response.json();
		})
		.then(data => {
			userModalElement.hide();
			getData();
		});
	}

	</script>
	

The update operation involves modifying existing items in the database. We'll define a route to handle incoming PUT or PATCH requests to update items.

server.js
	
	app.get('/users/:id', async (request, response) => {
		const user = await User.findById(request.params.id);
		response.status(200).json(user);
	});

	app.put('/users/:id', async (request, response) => {
		const userId = request.params.id;
		// Fetch the user from the database
		const user = await User.findById(userId);
		user.name = request.body.name;
		user.email = request.body.email;
		user.age = request.body.age;
		const updatedItem = await user.save();
		response.status(200).json(updatedItem);
	});
	

Delete Operation (DELETE):


For Delete MongoDB Data from Node CRUD Application, so first we have to create Delete button in each row of data in user.html file and then after we have to create deleteData() JavaScript function which will send DELETE data request to node route by using DELETE POST method.

user.html
	
	<!doctype html>
	<html lang="en">
		<head>
			<!-- Required meta tags -->
			<meta charset="utf-8">
			<meta name="viewport" content="width=device-width, initial-scale=1">

			<!-- Bootstrap CSS -->
			<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

			<title>Build a CRUD App with Node.js and MongoDB</title>
		</head>
		<body>
			
			<div class="container">
				<h1 class="text-center mb-5 mt-5 text-danger"><b>Build a CRUD App with Node.js and MongoDB - Delete Data from MongoDB Database - 5</b></h1>
				<div class="card mb-5">
					<div class="card-header">
						<div class="row">
							<div class="col col-6">Sample Data</div>
							<div class="col col-6">
								<button type="button" class="btn btn-primary btn-sm float-end" onclick="makeModal('Add User', 'Add', 'insertData')">Add</button>
							</div>
						</div>
					</div>
					<div class="card-body">
						<div class="table-responsive">
							<table class="table table-bordered table-striped">
								<thead>
									<tr>
										<th>Name</th>
										<th>Email</th>
										<th>Age</th>
										<th>Action</th>
									</tr>
								</thead>
								<tbody id="dataArea"></tbody>
							</table>
						</div>
					</div>
				</div>
			</div>
		</body>
	</html>
	<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
	<div id="modalArea"></div>

	<script>

	var userModalElement;

	function makeModal(title, button_value, callback)
	{
		let html = `
		<div class="modal" tabindex="-1" id="userModal">
			<div class="modal-dialog">
				<div class="modal-content">
					<form id="userform">
						<div class="modal-header">
							<h5 class="modal-title">${title}</h5>
							<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
						</div>
						<div class="modal-body">
							<div class="mb-3">
								<label>Name</label>
								<input type="text" name="name" id="name" class="form-control" />
							</div>
							<div class="mb-3">
								<label>Email</label>
								<input type="email" name="email" id="email" class="form-control" />
							</div>
							<div class="mb-3">
								<label>Age</label>
								<input type="number" name="age" id="age" class="form-control" />
							</div>
						</div>
						<div class="modal-footer">
							<input type="hidden" name="user_id" id="user_id" />
							<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
							<button type="button" class="btn btn-primary" onclick="${callback}()">${button_value}</button>
						</div>
					</form>
				</div>
			</div>
		</div>
		`;

		document.querySelector('#modalArea').innerHTML = html;

		userModalElement = new bootstrap.Modal(document.getElementById('userModal'));

		userModalElement.show();
	}

	function insertData()
	{
		let formElement = document.getElementById('userform');
		const formData = new FormData(formElement);
		// Convert formData to JSON
		const jsonData = {};
		formData.forEach((value, key) => {
			jsonData[key] = value;
		});
		// Make a POST request using Fetch API
		fetch('/users', {
			method : 'POST',
			body : JSON.stringify(jsonData),
			headers : {
				'Content-Type': 'application/json'
			}
		})
		.then(response => {
			return response.json();
		})
		.then(data => {
			userModalElement.hide();
			getData();
		});
	}

	getData();

	function getData(){
		fetch('/users')
		.then(response => {
			return response.json();
		})
		.then(data => {
			let html = '';
			if(data.length > 0){
				data.map((row) => {
					html += `
					<tr>
						<td>${row.name}</td>
						<td>${row.email}</td>
						<td>${row.age}</td>
						<td>
							<button type="button" class="btn btn-warning btn-sm" onclick="fetchSingleData('${row._id}')">Edit</button>
							<button type="button" class="btn btn-danger btn-sm" onclick="deleteData('${row._id}')">Delete</button>
						</td>
					</tr>
					`;
				});
			} else {
				html = '<tr><td colspan="4" class="text-center">No Data Found</td></tr>';
			}
			document.getElementById('dataArea').innerHTML = html;
		});
	}

	function fetchSingleData(id){
		fetch(`/users/${id}`)
		.then(response => {
			return response.json();
		})
		.then(data => {
			makeModal('Edit User', 'Edit', 'editData');
			document.getElementById('name').value = data.name;
			document.getElementById('email').value = data.email;
			document.getElementById('age').value = data.age;
			document.getElementById('user_id').value = data._id;
		});
	}

	function editData(){
		let formElement = document.getElementById('userform');
		const formData = new FormData(formElement);
		let jsonData = {};
		formData.forEach((value, key) => { 
			jsonData[key] = value;
		});
		const userId = document.getElementById('user_id').value;
		fetch(`/users/${userId}`, {
			method : 'PUT',
			body : JSON.stringify(jsonData),
			headers : {
				'Content-Type': 'application/json'
			}
		})
		.then(response => {
			return response.json();
		})
		.then(data => {
			userModalElement.hide();
			getData();
		});
	}

	function deleteData(id){
		if(confirm("Are you sure you want to delete this?")){
			fetch(`/users/${id}`, {
				method : 'DELETE',
				headers : {
					'Content-Type': 'application/json'
				}
			})
			.then(response => {
				return response.json();
			})
			.then(data => {
				getData();
			});
		}
	}

	</script>
	

The delete operation involves removing items from the database. We'll define a route to handle incoming DELETE requests to delete items.

server.js
	
	app.delete('/users/:id', async (request, response) => {
		const userId = request.params.id;
		// Fetch the user from the database
		const user = await User.findById(userId);
		await user.deleteOne();
		response.status(200).json({ message : 'Deleted item' });
	});
	




Step 8: Testing Your Application:


For test Mongo DB Node.js CRUD application in browser, so we have goes to terminal and run node server.jsthis command which will start Node Development server and provide us http://localhost:3000/ base url of our Node Application.

Conclusion:


Congratulations! You've successfully built a Node.js CRUD application with MongoDB. This tutorial covered the basics, but there's still room for improvement and expansion. Feel free to explore additional features and functionalities to enhance your application further.

Tuesday 20 February 2024

Converting Dynamic HTML to PDF in Node.js with Puppeteer


In this tutorial, we'll learn how to convert HTML content to a PDF file using Puppeteer in a Node.js environment. Puppeteer is a Node library that provides a high-level API to control headless Chrome or Chromium over the DevTools Protocol, making it a powerful tool for automating web tasks, including generating PDF files from HTML content.


Converting Dynamic HTML to PDF in Node.js with Puppeteer


Prerequisites


Before we begin, ensure you have the following installed:

  • Node.js (with npm)
  • MySQL (for the database setup, optional for this tutorial)
  • Basic understanding of Node.js and JavaScript

Setting up the Project


First, let's set up a Node.js project and install the necessary dependencies.

Create a new directory for your project and navigate into it:

	
		mkdir html-to-pdf-nodejs
		cd html-to-pdf-nodejs
	

Initialize a new Node.js project:

	
		npm init -y
	

Install the required dependencies (Express, MySQL, Puppeteer, Open):

	
		npm install express mysql2 puppeteer open
	

Database Structure


For convert dynamic HTML to PDF we need to fetch data from MySQL table. So run below sql script which will create sampledata table in your database.

	
		CREATE TABLE `sampledata` (
		  `id` mediumint unsigned NOT NULL AUTO_INCREMENT,
		  `name` varchar(255) DEFAULT NULL,
		  `phone` varchar(100) DEFAULT NULL,
		  `email` varchar(255) DEFAULT NULL,
		  `address` varchar(255) DEFAULT NULL,
		  `postalZip` varchar(10) DEFAULT NULL,
		  `region` varchar(50) DEFAULT NULL,
		  `country` varchar(100) DEFAULT NULL,
		  PRIMARY KEY (`id`)
		) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
		
		INSERT INTO `sampledata` VALUES (1,'Stephen Taylor','1-802-830-1866','auctor.nunc@hotmail.com','5659 Luctus Rd.','21408','Dadra and Nagar Haveli','Poland'),(2,'Mason George','1-343-545-7768','mauris@aol.edu','Ap #221-6699 Lacus. St.','921307','FATA','Costa Rica'),(3,'Hasad Donaldson','1-666-557-3187','et.euismod@google.edu','Ap #383-4682 Ornare Av.','818143','Kinross-shire','United Kingdom'),(4,'Hall Holland','(805) 418-1538','tempor.est@icloud.com','P.O. Box 358, 7624 Tincidunt Avenue','486262','Madrid','Indonesia'),(5,'Adam Hampton','1-421-241-5178','cubilia.curae@google.ca','P.O. Box 161, 1859 Iaculis Av.','44837','Brussels Hoofdstedelijk Gewest','South Korea'),(6,'Elizabeth Allison','(538) 834-6212','elit.dictum@hotmail.edu','867-6580 At St.','33668','Jeju','Pakistan'),(7,'Neve Barber','1-552-311-0208','vestibulum.nec.euismod@google.com','224-8122 Donec Road','51174','Santa Catarina','Netherlands'),(8,'Fatima Pope','(619) 278-1176','nulla.integer@hotmail.couk','649-1054 Ipsum Rd.','748321','Bahia','Austria'),(9,'Shad Cobb','1-778-327-3349','dignissim.maecenas.ornare@outlook.edu','6983 Magna. Rd.','2163','Xīběi','Philippines'),(10,'Zephr Ruiz','1-544-316-1144','luctus.ipsum@google.ca','634-2043 Cras Avenue','3845','Mecklenburg-Vorpommern','Sweden'),(11,'Juliet Lynn','(375) 573-6793','proin.dolor.nulla@yahoo.net','Ap #179-6441 Cum Rd.','71829','Calabria','Turkey'),(12,'Candice Medina','1-441-292-1278','integer.vulputate@icloud.org','953-188 Et Rd.','440326','Vorarlberg','Australia'),(13,'Rhea Roach','(635) 768-6867','vitae.velit@icloud.edu','543-5616 Sem Av.','869566','Burgenland','Canada'),(14,'Dean Hendrix','(362) 760-8321','nunc.pulvinar@protonmail.ca','Ap #905-5267 Arcu Street','6755-4242','National Capital Region','Indonesia'),(15,'Malachi Mitchell','1-586-881-4174','eget.lacus.mauris@icloud.ca','P.O. Box 183, 1479 Massa. St.','367458','Västra Götalands län','Indonesia'),(21,'Gabriel Acevedo','1-215-463-4511','dictum.cursus@outlook.com','5681 Sit Rd.','28846','Lombardia','Italy'),(22,'Beau Norris','1-563-287-4004','eros@google.edu','Ap #533-2583 Duis Rd.','R8T 1S4','Eastern Visayas','United States'),(23,'Kylan Mckinney','1-533-833-5567','eleifend.vitae@hotmail.net','333-2972 Nec, Road','72866','Leinster','Australia'),(24,'Stone Parsons','1-584-246-2228','aenean@outlook.com','923-5509 Etiam Street','Y1R 5X7','Zamboanga Peninsula','Nigeria'),(25,'Neve Sweet','(764) 167-2572','tellus.aenean@aol.net','558-1070 Sed, St.','1023 PS','Vienna','United Kingdom');
	

Creating the Server and HTML Template


Now, let's create a basic Express server that serves an HTML page with sample data fetched from a MySQL database. We'll also include a button to trigger the conversion of the HTML to a PDF file.

Create a file named app.js with the following content:

app.js
	
		const express = require('express');
		const mysql = require('mysql2');
		//Add puppeteer library
		const puppeteer = require('puppeteer');
		const app = express();
		const port = 3000;
		app.use(express.json());
		//Serve static files (including index.html) from the root directory
		app.use(express.static(__dirname));
		const database = mysql.createConnection({
			host : 'localhost',
			user : 'root',
			password : '123456789',
			database : 'testing'
		});

		database.connect((error)=> {
			if(error){
				console.error('Error connecting to MySQL : ', error);
			} else{
				console.log('Connected to MySQL database');
			}
		});

		app.get('/data', (request, response) => {
			response.sendFile(__dirname + '/data.html');
		});

		app.post('/getData', (request, response) => {
			database.query('SELECT * FROM sampledata', async (error, results) => {
				response.status(200).json(results);
			});
		});

		app.listen(port, () => {
			console.log(`Server is running on http://localhost:${port}`);   
		});
	

Create a file named data.html with the following content:

	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>How to Convert HTML to PDF in Node.js using Puppeteer</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">How to Convert HTML to PDF in Node.js using Puppeteer</h1>
					<div class="card">
						<div class="card-header">
							<div class="row">
								<div class="col col-6">Sample Data</div>
								<div class="col col-6">
									<a href="/convertPDF" class="btn btn-primary btn-sm float-end">Download in PDF</a>
								</div>
							</div>
						</div>
						<div class="card-body">
							<div class="table-responsive">
								<table class="table table-bordered table-striped">
									<thead>
										<tr>
											<th>Name</th>
											<th>Phone</th>
											<th>Email</th>
											<th>Address</th>
											<th>Zip</th>
											<th>Region</th>
											<th>Country</th>
										</tr>
									</thead>
									<tbody id="dataArea"></tbody>
								</table>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>
			getData();
			function getData(){
				fetch('/getData', {
					method: 'POST'
				})
				.then(response => {
					return response.json();
				})
				.then(data => {
					if(data.length > 0){
						let html = '';
						for(let i = 0; i < data.length; i++){
							html += `
							<tr>
								<td>${data[i].name}</td>
								<td>${data[i].phone}</td>
								<td>${data[i].email}</td>
								<td>${data[i].address}</td>
								<td>${data[i].postalZip}</td>
								<td>${data[i].region}</td>
								<td>${data[i].country}</td>
							</tr>
							`;
						}
						document.getElementById('dataArea').innerHTML = html;
					}
				})
				.catch(error => {
					// Handle errors
					//console.error(error);
					alert(error);
				});
			}
		</script>
	

Save this code in the root directory of your project.

HTML to PDF Conversion


We'll define a function convertHTMLToPDF in app.js file that takes HTML content as input, converts it to a PDF file using Puppeteer, and opens the generated PDF file.

app.js
	
		async function convertHTMLToPDF(htmlContent, pdfFilePath, margins = {top: '10mm', right: '10mm', bottom: '10mm', left: '10mm'}){
			const browser = await puppeteer.launch();
			const page = await browser.newPage();
			// Set the page content
			await page.setContent(htmlContent);
			// Generate PDF
			await page.pdf({ path : pdfFilePath, format : 'A4', margin : margins });
			// Open the generated PDF file in the default PDF viewer
			const open = await import('open');
			await open.default(pdfFilePath);
			//close the browser
			await browser.close();
		}
	

Serving HTML and Triggering Conversion


Finally, we'll set up routes to fetch data from MySQL table and convert into HTML and serve the HTML data and trigger the conversion to PDF when the user clicks on Download in PDF button.

app.js
	
		app.get('/convertPDF', async (request, response)=>{
			database.query('SELECT * FROM sampledata', async (error, results) => {
				let html = '';
				if(results.length > 0){
					html += `
					<table width="100%" border="1" cellpadding="5" cellspacing="0">
						<tr>
							<th width="20%">Name</th>
							<th width="10%">Phone</th>
							<th width="20%">Email</th>
							<th width="20%">Address</th>
							<th width="10%">Zip</th>
							<th width="10%">Region</th>
							<th width="10%">Country</th>
						</tr>
					`;
					results.map((row)=>{
						html += `
						<tr>
							<th>${row.name}</th>
							<th>${row.phone}</th>
							<th>${row.email}</th>
							<th>${row.address}</th>
							<th>${row.postalZip}</th>
							<th>${row.region}</th>
							<th>${row.country}</th>
						</tr>
						`;
					});
					html += `
					</table>
					`;
				}
				await convertHTMLToPDF(html, 'data.pdf');
			});
		});
	

Running the Server


To run the server, execute the following command:

	
		node app.js
	

Visit http://localhost:3000/data in your web browser to see the sample data table. Click the "Download in PDF" button to convert the HTML table to a PDF file.

Conclusion


Congratulations! You've learned how to convert HTML content to a PDF file in Node.js using Puppeteer. This technique can be useful for generating PDF reports, invoices, or any other printable documents from dynamic HTML content.

Feel free to customize the code to suit your specific requirements and explore additional features offered by Puppeteer for web automation and PDF generation.

Complete Source Code


app.js
	
		const express = require('express');
		const mysql = require('mysql2');
		//Add puppeteer library
		const puppeteer = require('puppeteer');
		const app = express();
		const port = 3000;
		app.use(express.json());
		//Serve static files (including index.html) from the root directory
		app.use(express.static(__dirname));
		const database = mysql.createConnection({
			host : 'localhost',
			user : 'root',
			password : '123456789',
			database : 'testing'
		});

		database.connect((error)=> {
			if(error){
				console.error('Error connecting to MySQL : ', error);
			} else{
				console.log('Connected to MySQL database');
			}
		});

		app.get('/data', (request, response) => {
			response.sendFile(__dirname + '/data.html');
		});

		app.post('/getData', (request, response) => {
			database.query('SELECT * FROM sampledata', async (error, results) => {
				response.status(200).json(results);
			});
		});

		async function convertHTMLToPDF(htmlContent, pdfFilePath, margins = {top: '10mm', right: '10mm', bottom: '10mm', left: '10mm'}){
			const browser = await puppeteer.launch();
			const page = await browser.newPage();
			// Set the page content
			await page.setContent(htmlContent);
			// Generate PDF
			await page.pdf({ path : pdfFilePath, format : 'A4', margin : margins });
			// Open the generated PDF file in the default PDF viewer
			const open = await import('open');
			await open.default(pdfFilePath);
			//close the browser
			await browser.close();
		}

		app.get('/convertPDF', async (request, response)=>{
			database.query('SELECT * FROM sampledata', async (error, results) => {
				let html = '';
				if(results.length > 0){
					html += `
					<table width="100%" border="1" cellpadding="5" cellspacing="0">
						<tr>
							<th width="20%">Name</th>
							<th width="10%">Phone</th>
							<th width="20%">Email</th>
							<th width="20%">Address</th>
							<th width="10%">Zip</th>
							<th width="10%">Region</th>
							<th width="10%">Country</th>
						</tr>
					`;
					results.map((row)=>{
						html += `
						<tr>
							<th>${row.name}</th>
							<th>${row.phone}</th>
							<th>${row.email}</th>
							<th>${row.address}</th>
							<th>${row.postalZip}</th>
							<th>${row.region}</th>
							<th>${row.country}</th>
						</tr>
						`;
					});
					html += `
					</table>
					`;
				}
				await convertHTMLToPDF(html, 'data.pdf');
			});
		});


		app.listen(port, () => {
			console.log(`Server is running on http://localhost:${port}`);   
		});
	

data.html
	
		<!doctype html>
		<html lang="en">
			<head>
				<!-- Required meta tags -->
				<meta charset="utf-8">
				<meta name="viewport" content="width=device-width, initial-scale=1">

				<!-- Bootstrap CSS -->
				<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

				<title>How to Convert HTML to PDF in Node.js using Puppeteer</title>
			</head>
			<body>
				
				<div class="container">
					<h1 class="text-center mb-5 mt-5">How to Convert HTML to PDF in Node.js using Puppeteer</h1>
					<div class="card">
						<div class="card-header">
							<div class="row">
								<div class="col col-6">Sample Data</div>
								<div class="col col-6">
									<a href="/convertPDF" class="btn btn-primary btn-sm float-end">Download in PDF</a>
								</div>
							</div>
						</div>
						<div class="card-body">
							<div class="table-responsive">
								<table class="table table-bordered table-striped">
									<thead>
										<tr>
											<th>Name</th>
											<th>Phone</th>
											<th>Email</th>
											<th>Address</th>
											<th>Zip</th>
											<th>Region</th>
											<th>Country</th>
										</tr>
									</thead>
									<tbody id="dataArea"></tbody>
								</table>
							</div>
						</div>
					</div>
				</div>

				<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
			</body>
		</html>

		<script>
			getData();
			function getData(){
				fetch('/getData', {
					method: 'POST'
				})
				.then(response => {
					return response.json();
				})
				.then(data => {
					if(data.length > 0){
						let html = '';
						for(let i = 0; i < data.length; i++){
							html += `
							<tr>
								<td>${data[i].name}</td>
								<td>${data[i].phone}</td>
								<td>${data[i].email}</td>
								<td>${data[i].address}</td>
								<td>${data[i].postalZip}</td>
								<td>${data[i].region}</td>
								<td>${data[i].country}</td>
							</tr>
							`;
						}
						document.getElementById('dataArea').innerHTML = html;
					}
				})
				.catch(error => {
					// Handle errors
					//console.error(error);
					alert(error);
				});
			}
		</script>