Open In App

Upload and Retrieve Image on MongoDB using Mongoose

Improve
Improve
Like Article
Like
Save
Share
Report

Prerequisites: For getting started with this you should have some familiarity with NodeJS, ExpressJS, MongoDB, and Mongoose.

  • NodeJS: It is a free open-source server environment that uses JavaScript on the server and runs on various platforms (Windows, Linux, Unix, Mac OS X, etc.).It uses asynchronous programming.
  • ExpressJS: It is a NodeJS web application server framework, designed for building single-page, multi-page, and hybrid web applications. It is the de facto standard server framework for node.
  • MongoDB: MongoDB is a NoSQL database.MongoDB is a JSON document data store. It allows you to store and query JSON-style documents with a few smarts on top.
  • Mongoose: Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node. js. It manages relationships between data, provides schema validation, and is used to translate between objects in code and the representation of those objects in MongoDB.

To start, install the required packages and modules:

  • ExpressJS allows us to set up middleware to respond to HTTP Requests.
npm install express --save
  • The module “body-parser” enables reading (parsing) HTTP-POST data.
npm install body-parser --save
  • Mongoose is a MongoDB client library providing object modeling for use in an asynchronous environment. Mongoose supports both promises and callbacks.
npm install mongoose --save
  • Multer is nodejs middleware used for uploading files.
npm install multer --save
  • Dotenv is a zero-dependency module that loads environment variables from a .env file into process.env.
npm install dotenv --save
  • EJS (Embedded Javascript) is a templating engine for nodejs. This engine helps to create an HTML page via templates with minimal code.
npm install ejs --save
  • nodemon is a developer tool that automatically restarts the node application when file changes in the code directory are detected.  It improves the developer experience when working on node-based applications.  Since this is a development tool and not part of our application code, we use `–save-dev` when installing this module:
npm install nodemon --save-dev

Project Structure:

 

Now let’s start coding!  To upload an image and retrieve an image by MongoDB using Mongoose, follow each of the steps below one by one.

  • Step 1: Create the file `.env` that will contain environment-specific settings.

Javascript

  • Step 2: Create our server file `app.js`.  Add the following code to it:

Javascript




var express = require('express')
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose')
var imgSchema = require('./model.js');
var fs = require('fs');
var path = require('path');
app.set("view engine", "ejs");
require('dotenv').config();
 
mongoose.connect(process.env.MONGO_URL)
.then(console.log("DB Connected"))
 
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
 
var multer = require('multer');
 
var storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, 'uploads')
    },
    filename: (req, file, cb) => {
        cb(null, file.fieldname + '-' + Date.now())
    }
});
 
var upload = multer({ storage: storage });
 
app.get('/', (req, res) => {
    imgSchema.find({})
    .then((data, err)=>{
        if(err){
            console.log(err);
        }
        res.render('imagepage',{items: data})
    })
});
 
 
app.post('/', upload.single('image'), (req, res, next) => {
 
    var obj = {
        name: req.body.name,
        desc: req.body.desc,
        img: {
            data: fs.readFileSync(path.join(__dirname + '/uploads/' + req.file.filename)),
            contentType: 'image/png'
        }
    }
    imgSchema.create(obj)
    .then ((err, item) => {
        if (err) {
            console.log(err);
        }
        else {
            // item.save();
            res.redirect('/');
        }
    });
});
 
var port = process.env.PORT || '3000'
app.listen(port, err => {
    if (err)
        throw err
    console.log('Server listening on port', port)
})


  • Step 3: Once we have established a connection to our database and required all the necessary packages, we can now begin defining our server-side logic. So for storing an image in MongoDB, we need to create a schema with mongoose. For that create the file `model.js` file and define the schema. The important point here is that our data type for the image is a Buffer which allows us to store our image as data in the form of arrays.

Javascript




var mongoose = require('mongoose');
var imageSchema = new mongoose.Schema({
    name: String,
    desc: String,
    img:
    {
        data: Buffer,
        contentType: String
    }
});
 
module.exports = mongoose.model('Image', imageSchema);


  • Step 4: This is the HTML template for the “upload page”. Notice that the src parameter for the <img> is not a typical URL. This format enables displaying the image stored in binary format in the Mongo database, and we convert it to base64 so that the browser can render it.
    Add the following code to the `views/imagePage.ejs`:

HTML




<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Image Uploading</title>
  </head>
 
  <body>
    <h1>To Upload Image on mongoDB</h1>
    <hr />
    <div>
      <form action="/" method="POST" enctype="multipart/form-data">
        <div>
          <label for="name">Image Title</label>
          <input
            type="text"
            id="name"
            placeholder="Name"
            value=""
            name="name"
            required
          />
        </div>
        <div>
          <label for="desc">Image Description</label>
          <textarea
            id="desc"
            name="desc"
            value=""
            rows="2"
            placeholder="Description"
            required
          >
          </textarea>
        </div>
        <div>
          <label for="image">Upload Image</label>
          <input type="file" id="image" name="image" value="" required />
        </div>
        <div>
          <button type="submit">Submit</button>
        </div>
      </form>
    </div>
 
    <hr />
 
    <h1>Uploaded Images</h1>
    <div>
      <% items.forEach(function(image) { %>
      <div>
        <div>
          <img
            src="data:image/<%=image.img.contentType%>;base64,
                    <%=image.img.data.toString('base64')%>"
          />
          <div>
            <h5><%= image.name %></h5>
 
            <p><%= image.desc %></p>
          </div>
        </div>
      </div>
      <% }) %>
    </div>
  </body>
</html>


  • Step 5: Create the directory `uploads` that will hold our uploaded images.
  • Step 6: Start the server by running the command: `nodemon app.js`

Output Open your browser to http://localhost:3000/ .  You should now see:
 

Demo



Last Updated : 30 Mar, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads