[wpdm_package id=’1987′]
Category: Node.js
Android chat app in Kotlin and Node JS
We created a chat application in native Android using Kotlin and Node JS. We have used Mongo DB as a database.
Modern and professional UI












End-to-end encryption
Usually, we use encryption but on server side. It has a security issue i.e. plain messages are transmitted through a network that can be read or altered in-transit.
But in this app, we have implemented end-to-end encryption means the encryption and decryption is done on client side rather than on server side. Client will encrypt the message and send it to the server. Server will send the encrypted message to the receiver and the receiver client will do the decryption. So even the server will not be able to read your messages.
We will be using the AES-256-bit length key to generate secret keys. All messages are sent to the server after encryption. So data will remain safe in-transit.
Voice notes
Sending voice notes is a quick way to send messages especially when you are in places when you are in hurry. Instead of typing the message which might cause spelling mistake, you can simply record your audio and send it directly to the receiver inside the app. No need to record the audio from a separate app and attach the audio in a message. You can also listen to your sent or received voice notes within the app.
If you use WhatsApp, you already know how voice notes work. You will learn how to record audio from your android phone and save it in your phone’s storage. Once stored, we will send that MP3 file to the Node JS server. The server will save the file. The user will be able to play that audio from the URL.
All contacts
We are using android contact’s API to fetch all the contacts. So you will learn how to get runtime contacts permission in android.
Private chat
The user can chat with any of his contact numbers as long as the receiver is a registered user.
Chat attachments
Users can attach files in chat messages as well. Images and videos are not compressed at all. So the receiver will see the image in its original quality.
Search contacts
Group chat
Users can chat in groups. Create as many groups as you want. Add members to them and start chatting. What makes it different from other chat apps ? First, it does not allow anyone to add you to a group. You will be invited. You will only start receiving the group notifications when you accept the invitation. Second, this app displays a list of all groups separately. So you can know in which groups you are currently in.
Share status that disappears after 24 hours
In this tutorial, you will:
- Be able to share your status with all your contacts
- Exclude some contacts from viewing your status
- Create multiple lists (e.g. friends, family, colleagues, etc.) so you won’t have to select the contacts each time you upload a status
- See contacts who have viewed your status/story
- Download the image or video of status
Seen/unseen messages (blue ticks)
In this part, you will learn how to:
- Install sockets in android
- Connect android sockets with the Node JS server
- Get real-time events on new message
- Mark messages as read and un-read
- Get bluetick (like WhatsApp) when the user sees your message
User profile
Search messages
Learn how to apply case in-sensitive sub-string search on all the messages in a chat with any of your contact. You can write any part of text of message and the app will show you the messages that matched your searched string.
Although the messages are end-to-end encrypted, which means that the server will not be able to apply search because server can’t read your messages. But we still found a way to apply search on end-to-end encrypted messages.
How to install
Our TrustPilot Reviews

Ecommerce website in MEVN stack
It is a single-page ecommerce website developed in Vue JS. Vue JS is an open-source Javascript framework specifically built to design user interfaces and is widely used for creating single-page applications.
Node JS is a Javascript run-time environment developed for creating the backend of applications. Its framework Express is widely used for creating APIs. It is built to create scalable applications.
Mongo DB is a no-SQL database. It is a non-relational database system. It is easily scalable because the data is loosely coupled.
Features | Free | Premium $100 |
---|---|---|
Product management (admin panel) | Yes | Yes |
Product listing | Yes | Yes |
Product detail | Yes | Yes |
Shopping cart | Yes | Yes |
Checkout (PayPal & Stripe) | Yes | Yes |
Order management (admin panel) | Yes | Yes |
Order detail | Yes | Yes |
Product specifications | Yes | Yes |
Stock management | Yes | Yes |
Search and sort | Yes | Yes |
New order email | Yes | Yes |
Product reviews | No | Yes |
Shipping charges by country | No | Yes |
Product image compression | No | Yes |
Realtime chat between users and admin | No | Yes |
Following is the feature list of this project:
- Product management (admin panel)
- Product listing
- Product detail
- Shopping cart
- Checkout (PayPal & Stripe)
- Order management (admin panel)
- Order detail
- Product specifications
- Stock management
- Product reviews
- Search and sort
- Shipping charges by country
- Email to admin whenever a new order is placed
- Product image compression
- Realtime chat between users and admin
Add product
Admin will be able to add products. He will enter the name of the product. Add a little description of the product. And set the price of the product. The price will be in dollars. Along with them, the admin can upload one or more images of the product.
Product listing
Users will see the products added by the admin on their home page. The latest products are displayed first. Along with each product, a button will be displayed to view the detail of the product.
Product detail
Users can view the detail of the product. If the product contains more than one image, then it will be displayed as a beautiful slider. From this page, users will also be able to add products to the cart. If the product is already added to the cart, then he will be able to remove it from the cart.
Shopping cart
Users can add the product to the cart. From the cart’s page, he will be able to adjust the quantity of the product. There will be multiple products in the cart and you can set the quantity of each product separately. You will also see your total bill as soon as you change the quantity of any product added to the cart.
Checkout (Stripe & PayPal)
After adding the products to the cart and setting each product’s quantity, the user can go to the checkout page. Here, he can either pay via Stripe or PayPal. Both payment methods accept debit and master cards securely. When the user made the payment, his payment is verified from the server. If verified, then a new order will be created in the database.
Order management
Whenever a user made a payment via Stripe or PayPal, an order will be created. All orders will be displayed on the admin panel ordered by latest to oldest. By default, the status of the order is “Processing”. But admin can change the status of the order to “Completed” when the product is delivered to the customer.
Admin will also be able to view the total amount of the order, the payment method customer has used, and the user’s shipping details.
Order detail
Admin can view all the products that were included in each order. He can manually verify the payment by clicking the payment method. If he clicks “Stripe”, he will be redirected to the Stripe payments page. If he clicks “PayPal”, then he will be redirected to the PayPal business page. Admin can check the name, email, and phone of the user and also his shipping address.
Product specifications
Admin can add the specifications of each product and the user will be able to see it on the product detail page.
Stock management
Admin can set the number of units in stock for each product. When the user makes an order, then the number of units he has selected will be subtracted.
Product reviews
User can give reviews on a product and it will be displayed to all users who visit that product. Admin will have the ability to remove any review, for example, spamming, etc.
Search and sort
Users can search by product by its name, description, category, or specifications. Users can also sort the products by date or by price.
Shipping charges by country
Admin can set the shipping charges by each country because, in a global eCommerce website, users place orders from all over the world. For example, if your store is located in USA and someone places an order from the UK. Then you charge the shipping fee differently than other countries.
Email to admin whenever a new order is placed
Admin will receive an email whenever a new order has been placed by the user.
Product image compression
Now you can compress the product images from the admin panel. The 3 MB image can be reduced to just 182 KB and the image will still be of great quality.
Realtime chat between users and admin
Users will be able to have a chat with the admin to know more about a product before placing an order. I believe every eCommerce website should have this feature.
We are constantly updating this project and adding more features and enhancements to it. Following are all the builds that are released till today.
- In the very first release, we build the basic E-commerce version where the admin can add products and users can see them. Add them to carts and order them. We also added Stripe and PayPal payment methods.
- In the second release, we added more features. Allowing users to give reviews about a product. Allowing admin to charge a different shipping fee for each country and many more.
- In the third release, we added functionality to compress product images and to have real-time chat between users and admin.
Free version
Password-less authentication in Node JS, Mongo DB
In this tutorial, we will teach you how to develop a password-less authentication system in Node JS and Mongo DB. We will create a simple form with just one field, email. The user will enter his email address and hit submit. As the form submits, we are going to send him an email with a verification code and also redirect him to a new page to enter that verification code. As soon as he enters the verification code and hit submit, we will check that code against that email address, if verified, then we will show him a success message. Otherwise, we will show him an error message. You can write your own authentication logic in either JWT or in sessions.
Video tutorial:
Let’s get started – Password-less authentication
First, you need to create an empty folder for your project. Then open the command prompt or terminal in that folder and run the following command:
npm init
It will ask some configuration questions, you can press enter for all to set the default values. Then run the following command to install the required modules:
npm install express http mongodb nodemailer express-formidable ejs
Then create a file named server.js and run the following command to start the server:
nodemon server.js
Write the following code in server.js:
server.js
const express = require("express")
const app = express()
const http = require("http").createServer(app)
const expressFormidable = require("express-formidable")
app.use(expressFormidable())
// we will be using EJS for templating
app.set("view engine", "ejs")
const mongodb = require("mongodb")
const mongoClient = mongodb.MongoClient
const nodemailer = require("nodemailer")
const port = process.env.PORT || 3000
http.listen(port, function () {
console.log("Server started at: " + port)
mongoClient.connect("mongodb://localhost:27017", function (error, client) {
if (error) {
console.error(error)
return
}
const db = client.db("password_less_authentication")
console.log("Database connected")
// [login route goes here]
app.get("/", function (request, result) {
result.render("index")
})
})
})
This will first include all the modules and set the templating engine to EJS. We will be using express-formidable middleware to handle input values from HTML form. Starts the HTTP server at port 3000. If you are on a production, then process.env.PORT will get the port as per your hosting server. Open the URL http://localhost:3000/ in your browser. You might see an error that “the index.ejs is not found in views directory”. So go ahead and create a folder named “views” at the root of your project. Inside this folder, create a file named “index.ejs”. Following will be the content of that file:
index.ejs
<form method="POST" action="/login">
<input type="email" name="email" placeholder="Enter email" />
<input type="submit" value="Login" />
</form>
Refresh your page and now you will see a simple email input field and a submit button. User does not have to remember the password, an email will automatically be sent to him with a verification code. This is the beauty of password-less authentication system. When this form submits, it redirects to the “/login” POST route. So we need to create that route in our “server.js” file at the place of [login route goes here] section:
// server.js
app.post("/login", async function (request, result) {
const email = request.fields.email
const hash = Math.floor(100000 + Math.random() * 900000)
const user = await db.collection("users").findOne({
email: email
})
if (user == null) {
await db.collection("users").insertOne({
email: email,
hash: hash
})
} else {
await db.collection("users").findOneAndUpdate({
_id: user._id
}, {
$set: {
hash: hash
}
})
}
const transport = nodemailer.createTransport({
host: "mail.yourdomain.com",
port: 465,
secure: true,
auth: {
user: "your email address",
pass: "your password"
}
})
const info = await transport.sendMail({
from: "Your email address",
to: email,
subject: "Verification",
text: "Your verification code is " + hash,
html: "Your verification code is <b>" + hash + "</b>"
})
console.log(info)
result.render("verification", {
email: email
})
})
// [verify route goes here]
This will first get the email address from the form input field. Then it generates a random number of 6 digits, we will send this number in the email as a verification code. Then it creates a new user in the database if the user with that email address does not exist already. If the user already exists, then it will simply update the hash (verification code) of that user. And finally, it will send an email to the user with a verification code and display him a page to enter the verification code.
Make sure to change your domain name, email account, and password associated with that domain from where you want to send an email. If you refresh the page now, enter your email, and hit submit, you will be given an error that the view “verification” is not found. But you will receive an email with a verification code. Then we need to create a file named “verification.ejs” inside the “views” folder. Following will be the content of this file:
verification.ejs
<form method="POST" action="/verify">
<input type="hidden" name="email" value="<%= email %>" />
<input type="text" name="hash" placeholder="Enter verification code" />
<input type="submit" value="Verify" />
</form>
This will create a hidden input field for email. The email variable is sent from the server.js file in the previous step. A text field to enter the verification code from the email and a submit button. Then we need to create a POST route in the server.js that will handle this request. So write the following code in server.js file in [verify route goes here] section:
// server.js
app.post("/verify", async function (request, result) {
const email = request.fields.email
const hash = request.fields.hash
const user = await db.collection("users").findOne({
$and: [{
email: email
}, {
hash: parseInt(hash)
}]
})
if (user == null) {
result.send("Not logged in")
return
}
// do your login logic here
result.send("Logged in")
})
It simply checks if the user with that email address has the same verification code as entered in the text field. If the verification code is correct, then it displays a success message, otherwise, it displays an error message. In the success message place, you can write your own logic to do the authentication. Check out our tutorial to do the authentication via JWT token.
That’s how you can create a password-less authentication system in Node JS and Mongo DB. If you face any problems in following this, kindly do let me know. After downloading the following files, kindly run the command “npm update” at the root.
Deploy Node JS app on VPS or Dedicated server
In this article, we are going to teach you how you can deploy the Node JS app on a VPS (Virtual Private Server) or a dedicated server. Make sure you have Node JS, NPM (Node Package Manager), and PM2 (Process Manager) installed, you can run the following commands to see if they are installed.
node -v
npm -v
pm2
If any of them is not installed on your server, you can simply chat with your hosting provider’s customer support center or open a ticket and ask them to install these for you. The main thing you are going to need for deployment is pm2.
Install Node JS
To install specific version of Node JS, first you need to install NVM (Node Version Manager).
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
Then you need to reload your shell configurations.
source ~/.bashrc
You can verify your installation of NVM by running the following command.
nvm -v
It will show you your NVM version (0.39.5 at the time of writing this). Then run the following command to list all available Node JS versions.
nvm ls-remote
You can install the specific version of Node JS by running:
nvm install 22.11.0
Here, 22.11.0 is the latest LTS version at the time of writing this post. You can set it accordingly. In order to make your NVM to use the installed version by default, you can run the following 2 commands.
nvm default 22.11.0
nvm alias default 22.11.0
If everything goes well, you can run the following command to verify that the Node JS has been successfully installed in your VPS or dedicated server.
node -v
Install PM2 (Process Manager)
If pm2 is not installed in your server, you can install is by running the following command:
npm install -g pm2
Creating a Node JS server
First, create a sub-domain for example “node.adnan-tech.com”. It will also create a directory for this sub-domain. Then create a simple Node JS app in it by running the following command in your cPanel terminal:
npm init
Press Enter key for all questions to set the default values. Then install the following modules:
npm install express http cors express-formidable socket.io
Inside the directory created for the sub-domain, create a file named “server.js” and write the following code in it:
server.js
const express = require("express")
const app = express()
const cors = require("cors")
app.use(cors())
const expressFormidable = require("express-formidable")
app.use(expressFormidable())
const http = require("http").createServer(app)
const socketIO = require("socket.io")(http, {
cors: {
origin: "*"
}
})
const port = process.env.PORT || 3000
http.listen(port, function () {
console.log("Server started at port: " + port)
socketIO.on("connection", function (socket) {
console.log("User connected: " + socket.id)
// [listen events here]
})
app.get("/", function (request, result) {
result.send("Hello world !")
})
// [create API here]
})
Then you need to tell your Node JS app that you will be using server.js as the main file. So open your package.json file and set the main key’s value to “server.js” as follows:
package.json
"main": "server.js",
Deploy the Node JS app
Now to start the server, first, open your “Terminal” from cPanel, and go to your subdomain by running the command:
cd yoursubdomain.com
Or whatever your subdomain path is. Then run the following command to start the server:
pm2 start server.js --name "Name of your app" --watch
–name is used to set a specific name for your app.
–watch is used to automatically restart the server if there is any change in the server.js file.
List all processes using pm2
You can view the list of all processed from the command:
pm2 list
If the write the URL https://yoursubdomain:3000/ in the browser, you will see the text “Hello world”. It means your Node JS server is successfully deployed on your VPS or dedicated server.
Create an API in Node JS
Now write the following code to create an API in the [create API here] section:
app.post("/myAPI", function (request, result) {
const name = request.fields.name
result.json({
status: "success",
message: "API has been called.",
data: "Your name is " + name
})
})
Then create an index.html file anywhere in your domain and write the following code to it to call an AJAX to this Node JS server.
index.html
<script>
const ajax = new XMLHttpRequest()
ajax.open("POST", "https://yoursubdomain:3000/myAPI", true)
ajax.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
console.log(this.responseText)
}
}
}
const formData = new FormData()
formData.append("name", "Adnan")
ajax.send(formData)
</script>
Open your browser console tab and you will see the message “Adnan”. Try changing the value in the “name” field in the formData object and refresh the page, you will now see your updated value.
Socket IO
You can also connect sockets to this Node JS server. In your index.html file, first, include the socket IO JS library using CDN:
<script src="https://cdn.socket.io/4.5.0/socket.io.min.js"></script>
Then write the following Javascript code to connect the client with the server:
<script>
const socketIO = io("https://yoursubdomain:3000")
</script>
After that, emit a simple event to the server:
// index.html
socketIO.emit("newEvent", { name: "Adnan" })
Then in your server.js, write the following code in place of the [listen events here] section:
// server.js
socket.on("newEvent", function (data) {
socket.emit("newEvent", data)
})
And finally, on your client side, you need to listen to this event and display a message in the browser console:
// index.html
socketIO.on("newEvent", function (data) {
console.log(data)
})
Refresh your page now and open your browser console. You will now see an object in the console. It means that your Node JS server’s sockets are running fine.
Stop the pm2 process
By default, the pm2 process will keep on running forever. If you want to stop the process, you can simply enter the following command in your cPanel terminal:
pm2 stop "Name of your app"
Run pm2 list and you will now see the status of your process as stopped.
Remove the pm2 process
Similarly, you can remove the pm2 process by running the following command:
pm2 delete "Name of your app"
Run pm2 list and you will no longer see your process in the list.
So that’s how you can deploy a Node JS app on your VPS or dedicated server. Check our tutorial to deploy Node JS app on the Heroku server. If you face any problems in following this, kindly do let me know.
How to create nested modules – Node JS
In this article, we are going to teach you, how you can have nested modules in your Node JS project. Nested modules help in splitting a large code-base into smaller files. This helps in debugging and scaling easily.
Video tutorial
Let’s say that you want to access the following URL:
http://localhost:3000/users/social
You want to have a “users” module where all user code will go. And you want the user’s module to be further divided into “social” module where all the code for user’s social networks will go, for example.
If you do not know how to create and set up a Node JS application, please check our this tutorial first.
So we will start by creating a user module. Create a new folder named “modules” at the root of your project. Then in this folder, create a file named “users.js”. The following code will go in the users.js file.
const express = require("express")
// [include social.js module]
module.exports = {
init: function (app) {
const userRouter = express.Router()
userRouter.get("/", function (request, result) {
result.send("Inside users.js")
})
app.use("/users", userRouter)
// [call init method of social.js here]
}
}
It creates a router object, named userRouter, from the express object. Then it tells the app to use this userRouter object for every route starting from “/users” in the URL. The init function accepts an app object which we will send from our main “server.js” file.
So go to your main “server.js” file and include the users module in it by writing the following line at the top.
const users = require("./modules/users")
const express = require("express")
const app = express()
Then, we need to call the init function of it and pass the app instance to it.
users.init(app)
If you access the following URL now, you will see a message “Inside users.js” in the browser:
http://localhost:3000/users
Now we need to create another file named “social.js” inside modules folder. The following will be the code for social.js file:
const express = require("express")
module.exports = {
init: function (userRouter) {
const socialRouter = express.Router()
socialRouter.get("/", function (request, result) {
result.send("Inside social.js")
})
userRouter.use("/social", socialRouter)
}
}
This module’s init method accepts userRouter as an argument that we had created in our “users.js” file. And it is using that userRouter object instead of app object because this module will be used only when the “/social” path is appended after the “/users” path.
The final thing you need to do is to call the init method of the “social.js” file inside our “users.js” file. So go to your “users.js” file and first include the social module in it. Write the following line in the [include social.js module] section:
const social = require("./social")
Then write the following code in the [call init method of social.js here] section:
social.init(userRouter)
So if you access the following URL now, you will be able to see “Inside social.js” in your browser.
http://localhost:3000/users/social
We created an E-commerce application in Node JS and Mongo DB where we used nested modules to have admin > products and orders. You can check that project from here.
So that’s how you can have nested modules in Node JS express framework. If you face any problems in following this, kindly do let me know.
Source code – How to create nested modules in Node JS
[wpdm_package id=’1736′]
Upload multiple images in Node JS and Mongo DB
In this article, we are going to teach you, how you can upload multiple images in Node JS and Mongo DB.
Video tutorial:
Initializing the project
First, you need to create an empty folder and open a command prompt or terminal in it. Then run the following command in that CMD:
> npm init
It will ask multiple questions, just press enter to set the default values.
Then you need to install the express and HTTP modules. So run the following command:
> npm install express http
Then create a file named server.js and write the following code in it:
const express = require("express")
const app = express()
const http = require("http").createServer(app)
// [include Mongo DB]
// [set view engine]
// [Express formidable and FS module]
// [recursive function to upload images]
const port = process.env.PORT || 3000
http.listen(port, function () {
console.log("Server started running at port: " + port)
// [connect Mongo DB]
})
If you open your CMD, you will see the message “Server started running at port: 3000”.
You can check your project from the URL: http://localhost:3000/
Installing Mongo DB
To install the Mongo DB module, first, run the following command in your terminal:
> npm install mongodb
Then include the Mongo DB module in your server.js file in the [include Mongo DB] section:
const mongoClient = require("mongodb").MongoClient
Then connect with the database by writing the following code in the [connect Mongo DB] section:
mongoClient.connect("mongodb://localhost:27017", async function (error, client) {
if (error) {
console.error(error)
return
}
const db = client.db("multiple_images_upload")
console.log("Database connected")
// [routes]
})
To learn more about Mongo DB, check our tutorials on Mongo DB here.
Display form to upload multiple images
To display an HTML file in Node JS, we need to install a module named EJS. You can install it by running the following command:
> npm install ejs
Then we need to tell our app to use the EJS as the templating engine. So write the following code in the [set view engine] section:
app.set("view engine", "ejs")
Then create a GET route in the [routes] section of server.js file:
app.get("/", async function (request, result) {
result.render("home")
})
Then create a folder named views and inside this folder create a new file named home.ejs. In this file, we will create a form with an input type file.
<!-- home.ejs -->
<form onsubmit="uploadImages()" enctype="multipart/form-data">
<input type="file" multiple accept="image/*" name="images" required />
<input type="submit" value="Upload images" />
</form>
multiple: This will allow multiple file uploads.
accept=”image/*”: This allows only image files to be uploaded.
Then we will create this Javascript function to call an AJAX.
<script>
function uploadImages() {
// prevent the form from reloading the page
event.preventDefault()
// get form tag
const form = event.target
// create form data object from <form>
const formData = new FormData(form)
// create AJAX object
const ajax = new XMLHttpRequest()
// 1st parameter = method, GET/POST
// 2nd parameter = path to server file
// 3rd parameter = asynchronous
ajax.open("POST", "/uploadImages", true)
// when status of request changes
ajax.onreadystatechange = function () {
// operation is completed
if (this.readyState == 4) {
// response from server is okay
if (this.status == 200) {
// response from server
console.log(this.responseText)
}
}
}
// send AJAX request
ajax.send(formData)
}
</script>
Comments have been added with each line for the explanation.
Upload multiple images in Node JS
To handle the form data object, we must first install the express-formidable and fs modules. FS stands for File System. To install these modules, run the following command:
> npm install express-formidable fs
Then you need to include these modules in your server.js file, in the [Express formidable and FS module] section:
const formidable = require("express-formidable")
app.use(formidable({
multiples: true, // request.files to be arrays of files
}))
const fileSystem = require("fs")
app.use("/uploads", express.static(__dirname + "/uploads"))
Then create a folder named uploads at the root of your project.
After that, create the following POST route to handle that AJAX request:
app.post("/uploadImages", async function (request, result) {
const images = []
if (Array.isArray(request.files.images)) {
for (let a = 0; a < request.files.images.length; a++) {
images.push(request.files.images[a])
}
} else {
images.push(request.files.images)
}
callbackFileUpload(images, 0, [], async function (savedPaths) {
await db.collection("images").insertOne({
images: savedPaths
})
result.send("Images has been uploaded.")
})
})
To upload images, we will be using a recursive function. So create a recursive function in the [recursive function to upload images] section:
function callbackFileUpload(images, index, savedPaths = [], success = null) {
const self = this
if (images.length > index) {
fileSystem.readFile(images[index].path, function (error, data) {
if (error) {
console.error(error)
return
}
const filePath = "uploads/" + new Date().getTime() + "-" + images[index].name
fileSystem.writeFile(filePath, data, async function (error) {
if (error) {
console.error(error)
return
}
savedPaths.push(filePath)
if (index == (images.length - 1)) {
success(savedPaths)
} else {
index++
callbackFileUpload(images, index, savedPaths, success)
}
})
fileSystem.unlink(images[index].path, function (error) {
if (error) {
console.error(error)
return
}
})
})
} else {
success(savedPaths)
}
}
Run the project now and you see a form with an input file and a submit button. Select multiple images from your computer and hit submit. Once submitted, you will see your uploaded images in the “uploads” folder and a new document will be created in the Mongo DB images collection.
Show uploaded images
Now we need to show all uploaded images. First, change your home route in server.js to the following:
app.get("/", async function (request, result) {
const images = await db.collection("images").find({}).toArray()
result.render("home", {
images: images.length > 0 ? images[0].images : []
})
})
This will pass all the images from the first document of images collection to the home file. Now go to your home.ejs and write the following for loop to display all images:
<%for (let a = 0; a < images.length; a++) { %>
<img src="<%= images[a] %>" style="width: 100%;" />
<% } %>
Refresh the page now and you will be able to view all uploaded images.
If you face any problem in this, please do not hesitate to get in touch with me.
To run the following downloaded files, run the following command in your terminal first:
> npm update
[wpdm_package id=’1727′]
Compress image in Node JS
In this tutorial, we are going to teach you, how you can compress image in Node JS. You can download and install Node JS from their official site.
Video tutorial: Compress image in Node JS
First, create a new folder. Open CMD in it. And run the following commands:
> npm init
> npm install express http
Then, create a file named “server.js” and write the following code in it:
const express = require("express")
const app = express()
const http = require("http").createServer(app)
// [other modules]
const port = process.env.PORT || 3000
http.listen(port, function () {
console.log("Server started running at port: " + port)
// [post route goes here]
// [get route goes here]
})
Then run the following commands in your terminal:
> npm install -g nodemon
> nodemon server.js
You will see a message saying the “Server started running at port: 3000”. You can access your server from the following URL:
http://localhost:3000
Now, we need to install the module for displaying views. And to get input from form fields. So, install the following modules:
> npm install ejs fs express-formidable
EJS module is used for displaying the HTML files. FS stands for File System, this module is used to handle files. And “express-formidable” is used for getting values from the input field. Make sure to run the “nodemon server.js” command again.
Install compress image module in Node JS
To install a module to compress image in Node JS, you need to run the following command in your terminal:
> npm install pngquant-bin@6.0.1 gifsicle@5.2.1 compress-images fs
Then, we need to include those modules in our project. So write the following lines in the [other modules] section:
const compressImages = require("compress-images")
const formidable = require("express-formidable")
app.use(formidable())
const fileSystem = require("fs")
app.set("view engine", "ejs")
Now, write the following lines in the [get route goes here] section:
app.get("/", function (request, result) {
result.render("index")
})
After that, you need to create a folder named “views” at the root of your project. And in that folder, create a file named “index.ejs”. Following will be the code of “index.ejs”:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Compress image</title>
</head>
<body>
<form method="POST" action="/compressImage" enctype="multipart/form-data">
<input type="file" name="image" accept="image/*" required />
<input type="submit" value="Compress image" />
</form>
</body>
</html>
It will display a simple HTML form with an input field and a submit button. Then, you need to create a POST route that will handle this request. The following code goes in the [post route goes here] section of the “server.js” file:
app.post("/compressImage", function (request, result) {
const image = request.files.image
if (image.size > 0) {
if (image.type == "image/png" || image.type == "image/jpeg") {
fileSystem.readFile(image.path, function (error, data) {
if (error) throw error
const filePath = "temp-uploads/" + (new Date().getTime()) + "-" + image.name
const compressedFilePath = "uploads/"
const compression = 60
fileSystem.writeFile(filePath, data, async function (error) {
if (error) throw error
compressImages(filePath, compressedFilePath, { compress_force: false, statistic: true, autoupdate: true }, false,
{ jpg: { engine: "mozjpeg", command: ["-quality", compression] } },
{ png: { engine: "pngquant", command: ["--quality=" + compression + "-" + compression, "-o"] } },
{ svg: { engine: "svgo", command: "--multipass" } },
{ gif: { engine: "gifsicle", command: ["--colors", "64", "--use-col=web"] } },
async function (error, completed, statistic) {
console.log("-------------")
console.log(error)
console.log(completed)
console.log(statistic)
console.log("-------------")
fileSystem.unlink(filePath, function (error) {
if (error) throw error
})
}
)
result.send("File has been compressed and saved.")
})
fileSystem.unlink(image.path, function (error) {
if (error) throw error
})
})
} else {
result.send("Please select an image")
}
} else {
result.send("Please select an image")
}
})
The last thing you need to do is to create two folders named “uploads” and “temp-uploads” at the root of your project. Here, all compressed images will be stored.
This will compress the image up to 60%. You can now try to select an image from the input file and hit “Compress image”. You will see a success message if everything goes right. And you will see your compressed image in the “uploads” folder.

Real-world example
We implemented this compression in one of our projects, so you can get the real-world example of image compression in Node JS.
So that’s how you can compress an image in Node JS. If you face any problems in following this, kindly do let us know.
Download source code
[wpdm_package id=’1704′]
Single page application in MEVN stack – Realtime chat
In this article, we are going to provide you with a free course to develop a full-fledged real-time chat app in MEVN (MongoDB, Express, Vue JS, and Node JS) Stack. Here M stands for MongoDB which we have used as a database. E stands for Express which is a Node JS framework. V stands for Vue JS which will be our front end. We will be creating a single-page application in Vue JS. And N stands for Node JS which will be our backend.
You can download Node JS from here. And Mongo DB from their official site.
Features | Free | Premium $100 |
---|---|---|
Sign up | Yes | Yes |
Login/logout | Yes | Yes |
Add contacts | Yes | Yes |
Private chat | Yes | Yes |
Message encryption | Yes | Yes |
Chat with attachment | Yes | Yes |
Realtime chat | Yes | Yes |
Email verification | No | Yes |
Reset password | No | Yes |
User profile | No | Yes |
Chat with emojis | No | Yes |
Bookmark messages | No | Yes |
Copy message | No | Yes |
Archive chat with password | No | Yes |
Group chat | No | Yes |
Notifications page | No | Yes |
Customer support | No | Yes |
We will do the deployment of this app on live servers. You can find the link to all the tutorials of this series here. Following are the topics we have covered in this series.
Installation of Node JS server

In the very first tutorial, we have done the installation of the Node JS server. We also connect our Node JS server with MongoDB. You can find the tutorial here.
Setup Vue JS CLI – A single page application

Then we set up our Vue JS app using CLI. We used Vue JS CLI because we will be creating a single page application. We will be using Vue 3. Right now, we will be using the app on the local server. But once it is done, we will teach you how you can create a production build of it. And also how you can make it live on your website. This tutorial can be found here.
Routing for single page application
As this is a single page application, so we will be doing routing using Vue components. You can learn how to implement routing in a single page Vue JS app from this tutorial.
Hello world

In this part, we will learn how to integrate Bootstrap into your Vue app. So you can design the theme as per your choice. We also show you how you can create header and footer layouts in Vue JS. The header and footer will be displayed on each page. For the header, we will be creating a simple Bootstrap navbar. And for the footer, we will simply be displaying copyright text and the current year dynamically.
Registration

You will learn how to display a form using Vue JS. Sends the form values to the Node JS server. And how Node JS can save the data in the MongoDB database. You will also learn how to check if certain data exists in MongoDB or not. Moreover, you will also learn how to encrypt the passwords before saving them in MongoDB. So even if your database gets stolen, your user’s passwords will remain unknown to the hacker.
One more thing you will learn in this part is how to deal with CORS (Cross-Origin Resource Sharing) errors in the Node JS server.
Email verification

After successful registration, an email will be sent to the user’s email address. That email will have the verification code. And the user will be redirected to a page where he can enter his verification code.
He will not be able to log in until he verifies his email address.
Login
In this part, we do the authentication. You will learn how to generate JWT (JSON Web Tokens) and how to store them in local storage for future usage. You will also learn how to validate the encrypted passwords saved in MongoDB while authenticating.
Reset Password
If a user forgets his password, he can reset it. He just needs to enter his email address. An email will be sent to him with a link to reset the password. When he clicks that link, he will be redirected to a page where he can enter his new password.
Get logged-in user’s data

We will learn how to call AJAX with headers in Vue JS. How Node JS server read the headers? And how to create middleware in Node JS.
Logout

We will teach you how to log out as a user from MongoDB and from the Vue JS client app. We will remove the JWT token we create in the login part.
Contacts

To chat with people, we need to add them to our contacts. We will be creating separate components in the Vue JS app for adding and displaying all contacts. We will also be creating a new module in the Node JS server. You will learn how to insert data in a nested array in MongoDB.
We will be calling AJAX requests using Axios in Vue JS. While deleting a contact, you will learn how to ask for confirmation using sweet alert dialogs.

You will also learn how to remove an element from a nested array in MongoDB.
Chat with attachments
This is the main module of this app. We advise you to please put more focus on this part. It teaches you how to import CSS in specific Vue components only. How to send input type file from the Vue JS app to the Node JS server. How Node JS saves files on the server.
Encryption and Decryption

We are saving messages in MongoDB in encrypted form. While fetching the messages, we are again decrypting the messages back to their original state. Even if someone has access to your database, he will not be able to read your messages. Because he does not have the key. The key will only be stored on the Node JS server.
You can see the messages are fully encrypted. On the home page, where we are displaying all user’s contacts, we will also be displaying unread messages from each contact.

Attachments uploaded with messages are also protected from direct URL access. So we will show you how you can convert a file in base64 string using Node JS. And download them to your system using the Vue JS app.

Realtime chat using Socket IO

Chat will be real-time. Meaning users do not have to refresh the page to see new messages. He will automatically receive a notification. If the chat is opened, then the incoming message will be appended automatically.
We have “load more” functionality. This means that we will only show 10 messages in each AJAX call. To get the previous 10 messages, the user will click on that button and we will fetch 10 more messages. So you will learn pagination using Node JS and Mongo DB too.
Deploy Node JS, Mongo DB, and Vue JS apps

We will be deploying our Node JS server on Heroku. You can check our Heroku guide here. We will be deploying MongoDB on mongodb.com. And we will be deploying our Vue JS app on any hosting provider we choose. For example, a2hosting, Bluehost, Siteground, etc. We will create a production-ready build of our Vue JS app and upload it on our live server.
However, you might face some problems going live. That’s why we have written a detailed complete tutorial on the deployment on all these 3 platforms.
Search Contact
You can search your contacts by their email address. Searching with their email address points you to the right person. Because multiple people can have the same name. But email is unique in the entire “users” collection in MongoDB.
Group chat

Previously we discussed private chat. In this tutorial series, we also cover the group chat feature. You will be able to create groups. Add members to the groups. You will be sending an invitation to the members to join the group. The other person can accept your request to join the group or can ignore it.
Any member can leave the group anytime he wants. But this is not the case for admins. For the admin to leave the group, he must first assign someone else to the admin of the group. The other person must be a member of the group. After assigning someone else as an admin, he can easily leave the group.
People who are not members or the admin of the group, cannot send or view the messages in the group chat.
The chat in the group is also real-time. All the other members of the group will get a notification when someone sends a message. If they have opened the group, then the new message will automatically get appended at the end of the chat.
Group chat is also end-to-end encrypted.
And same as we did for private chat, we are displaying several unread messages from a group on the page where we are displaying all groups.
Emojis

In chat, you can also send emojis to the recipient. Emojis are also encrypted.
Bookmark message
You can also bookmark your favorite messages. This way, you can always see your bookmarked messages whenever you want. You can bookmark your messages as well.
Copy message
If someone sends you a lengthy message, like an essay. You can copy the whole message with a single click.
Archive chat with password

- You can archive your private chat with a password.
- Once archived, no one will be able to view the chat.
- To view the chat, you must provide the correct password.
- You can remove the password by simply entering the correct password.
- Archived chats cannot be deleted. You must first un-archive the chat, then delete it.
Re-designed
I re-designed the website into a beautiful template. That’s how it looks now.

So you will be learning to create a full-stack chat app from scratch using Node JS, Mongo DB, and Vue JS. Again, you can find the tutorial for the complete series here. Enjoy!
Free version
https://github.com/adnanafzal565/spa-chat-app-mevn
Our Trustpilot reviews

Encrypt and Decrypt Strings using Node JS and Mongo DB
In this tutorial, we are going to teach you, how you can encrypt and decrypt the strings using Node JS and Mongo DB. The encrypted strings will be saved in the database and upon retrieval will be decrypted.
Setup the Project
First, create an empty folder and open a command prompt in it. Then run the following commands in it one by one:
npm init
npm install express http mongodb crypto ejs
npm install -g nodemon
nodemon server.js
crypto module will be used to encrypt and decrypt the strings. ejs module will be used to render HTML files. Then create a file named server.js at the root of folder. Open server.js file and write the following code in it:
// initialize express JS
const express = require("express");
const app = express();
// create HTTP server
const http = require("http").createServer(app);
// [include Mongo DB module here]
// start the server
http.listen(process.env.PORT || 3000, function () {
console.log("Server started running...");
// [connect with Mongo DB here]
});
Open your terminal and you will see the message that the server has been started. You can access your project at http://localhost:3000/
Setup Mongo DB
Write the following lines in place of [include Mongo DB module here] section in your server.js file:
// include mongo DB
var mongodb = require("mongodb");
var MongoClient = mongodb.MongoClient;
Then connect the database in the [connect with Mongo DB here] section:
// connect with mongo DB server
MongoClient.connect("mongodb://localhost:27017", function (error, client) {
if (error) {
console.error(error);
return;
}
// set database
db = client.db("encrypt_decrypt_string");
console.log("Database connected");
// [routes goes here]
});
Save the file and open your terminal, now you will see another message that the database has been connected as well.
Encrypt the String
First, include the crypto module at the top of your server.js file:
// include crypto module
const crypto = require("crypto")
// set encryption algorithm
const algorithm = 'aes-256-cbc'
// private key
const key = "adnan-tech-programming-computers" // must be of 32 characters
// random 16 digit initialization vector
const iv = crypto.randomBytes(16)
The key and initialization vector can be any string of 32 and 16 characters respectively. But it is recommended to keep the key hard-coded and initialization vector to be random. Because IV will be saved in database.
We cannot save the key in the database, because if the database gets hacked then all your encrypted strings will be compromised as well.
After that, create a GET route that will encrypt the string and save in Mongo DB. Write the following code in the [routes goes here] section:
// route to encrypt the message
app.get("/encrypt/:message", async function (request, result) {
// get message from URL
const message = request.params.message;
// random 16 digit initialization vector
const iv = crypto.randomBytes(16);
// encrypt the string using encryption algorithm, private key and initialization vector
const cipher = crypto.createCipheriv(algorithm, key, iv);
let encryptedData = cipher.update(message, "utf-8", "hex");
encryptedData += cipher.final("hex");
// convert the initialization vector to base64 string
const base64data = Buffer.from(iv, 'binary').toString('base64');
// save encrypted string along wtih initialization vector in database
await db.collection("strings").insertOne({
iv: base64data,
encryptedData: encryptedData
});
// show the encrypted message
result.send(encryptedData);
});
Save the file and try to access the URL: http://localhost:3000/encrypt/This is a test string
You can write any string in the URL and you will see the encrypted text in the browser and also in your Mongo DB.
Show all Encrypted Strings
To show all encrypted strings, we are going to use a module named ejs. Write the following line at the top of your server.js file:
// set templating engine as EJS
app.set("view engine", "ejs");
The create the following GET route to show all encrypted strings:
// route to show all encrypted messages
app.get("/", async function (request, result) {
// get all data from database
const data = await db.collection("strings")
.find({})
.sort({
_id: -1
}).toArray();
// render index.ejs
result.render("index", {
data: data
});
});
Create a new folder named views and inside it create a file named index.ejs. It will have the following code:
<table>
<% for (let d in data) { %>
<tr>
<td>
<a href="/decrypt/<%= data[d].encryptedData %>" target="_blank">
<%= data[d].encryptedData %>
</a>
</td>
</tr>
<% } %>
</table>
Access the URL: http://localhost:3000/ and you will see all your encrypted strings in descending order.
Decrypt the String
To decrypt the string, create a GET route and fetch the encrypted string and initialization vector from Mongo DB. Then we can apply the decryption using key.
// route to decrypt the message
app.get("/decrypt/:encrypted", async function (request, result) {
// get encrypted text from URL
const encrypted = request.params.encrypted;
// check if text exists in database
const obj = await db.collection("strings").findOne({
encryptedData: encrypted
});
if (obj == null) {
result.status(404).send("Not found");
return;
}
// convert initialize vector from base64 to buffer
const origionalData = Buffer.from(obj.iv, 'base64')
// decrypt the string using encryption algorithm and private key
const decipher = crypto.createDecipheriv(algorithm, key, origionalData);
let decryptedData = decipher.update(obj.encryptedData, "hex", "utf-8");
decryptedData += decipher.final("utf8");
// display the decrypted string
result.send(decryptedData);
});
If you click on any string now, you will see the actual string.
[wpdm_package id=’1554′]