Welcome folks today in this blog post we will be uploading image buffer & blob data
to mongodb
database in node.js and express and display it inside the browser using javascript. All the full source code of the application is shown below.
Get Started
In order to get started you need to make a new node.js
project using the below command as shown below
npm init -y
npm i express
npm i ejs
npm i multer
npm i mongoose
And after that you will see the below directory
structure of the node.js and express project as shown below
And after that you need to make the index.js
file and copy paste the following code
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
const express = require('express'); const multer = require('multer'); const mongoose = require('mongoose'); const app = express(); // set up middleware app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); app.set('view engine', 'ejs'); // connect to MongoDB mongoose.connect('mongodb://localhost:27017/node-mongo-image', { useNewUrlParser: true, useUnifiedTopology: true, }); // define schema for image const imageSchema = new mongoose.Schema({ name: String, image: { data: Buffer, contentType: String, }, }); // define model for image const Image = mongoose.model('Image', imageSchema); // set up multer const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // set up routes app.get('/', (req, res) => { res.render('index'); }); // start server app.listen(3000, () => { console.log('Server started on port 3000'); }); |
Here’s what in the above code we are using the below libraries
as shown below:
express
: A popular Node.js web framework
ejs
: A templating engine that allows us to easily render HTML pages
multer
: A middleware that handles multipart/form-data, which is used for uploading files
mongoose
: An ORM (Object-Relational Mapping) that provides a higher-level interface to MongoDB
This sets up an Express app with middleware for serving static files and parsing form data. It also sets up a connection to MongoDB using Mongoose, and defines a schema and model for storing image data. The multer
middleware is used to handle file uploads, and the routes for uploading and displaying images are set up.
Now we need to make the views
directory where we will be storing the index.ejs
file when someone goes to the /
route we will load this template
views/index.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Node.js MongoDB Image Upload Tutorial</title> </head> <body> <h1>Node.js MongoDB Image Upload Tutorial</h1> <hr /> <h2>Upload Image</h2> <form method="POST" action="/upload" enctype="multipart/form-data"> <div> <label for="name">Name:</label> <input type="text" name="name" id="name" /> </div> <div> <label for="image">Image:</label> <input type="file" name="image" id="image" /> </div> <div> <button type="submit">Upload Image</button> </div> </form> <hr /> <p><a href="/images">Uploaded Images</a></p> </body> </html> |
As you can see we have the simple html5
form where we allow the user to selct the image
file and then we are making the post
request to the /upload
endpoint. And then we are having the link
to allow the users to see the uploaded
images.
Now we will be writing the /upload
post request to actually take the selected image
file and then upload it using the multer
library first store it inside the memory
in the form of blob
and buffer and then we will be store that inside the mongodb
database and then we will be redirecting the users to the images.ejs
template as shown below
1 2 3 4 5 6 7 8 9 10 11 12 13 |
app.post('/upload', upload.single('image'), async (req, res) => { const image = new Image({ name: req.file.originalname, image: { data: req.file.buffer, contentType: req.file.mimetype, }, }); await image.save(); res.redirect('/images'); }); |
As you can see in the above code we are making the new object
where we are storing the name
and the actual image
object where we are storing the buffer and blob
data of the image and then mimetype
of the image. And then we are calling the save()
method to actually save the buffer data inside the mongodb database. And then we are redirecting the users to the /images
route.
Retrieving Blob and Buffer Image Data
Now guys we will be displaying the images
stored inside the mongodb database in the browser. For this we will be using the find()
method to retrieve the blob and buffer
data as shown below
1 2 3 4 5 |
app.get('/images', async (req, res) => { const images = await Image.find().sort({_id:-1}); res.render('images', { images: images }); }); |
Now we need to make the images.ejs
file in the views
directory and copy paste the following code
views/images.ejs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>Node.js MongoDB Image Upload Tutorial</title> </head> <style> .grid-container { display: grid; grid-template-columns: repeat(2, 1fr); grid-gap: 10px; } img { width: 100%; height: 100%; object-fit: cover; } </style> <body> <h1>Node.js MongoDB Image Upload Tutorial</h1> <hr /> <% if (images.length> 0) { %> <% images.forEach((image)=> { %> <div class="grid-container"> <h2> <%= image.name %> </h2> <img src="data:<%= image.image.contentType %>;base64,<%= image.image.data.toString('base64') %>" /> </div> <% }); %> <% } else { %> <p>No images uploaded yet.</p> <% } %> </body> </html> |
As you can see we are displaying the images
using the ejs
syntax and then we are converting the blob
data of the image to the base64
string and displaying it inside the img
tag as shown below
FULL SOURCE CODE
index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
const express = require('express'); const multer = require('multer'); const mongoose = require('mongoose'); const app = express(); // set up middleware app.use(express.static('public')); app.use(express.urlencoded({ extended: true })); app.set('view engine', 'ejs'); // connect to MongoDB mongoose.connect('mongodb://localhost:27017/node-mongo-image', { useNewUrlParser: true, useUnifiedTopology: true, }); // define schema for image const imageSchema = new mongoose.Schema({ name: String, image: { data: Buffer, contentType: String, }, }); // define model for image const Image = mongoose.model('Image', imageSchema); // set up multer const storage = multer.memoryStorage(); const upload = multer({ storage: storage }); // set up routes app.get('/', (req, res) => { res.render('index'); }); app.post('/upload', upload.single('image'), async (req, res) => { const image = new Image({ name: req.file.originalname, image: { data: req.file.buffer, contentType: req.file.mimetype, }, }); await image.save(); res.redirect('/images'); }); app.get('/images', async (req, res) => { const images = await Image.find().sort({_id:-1}); res.render('images', { images: images }); }); // start server app.listen(3000, () => { console.log('Server started on port 3000'); }); |