Norse
Norse

Reputation: 648

Strategy for uploading images to mongoDB Atlas with multer?

My goal is to be able to upload images to mongoDB Atlas with the use of Multer. Currently, I have set up an example with express-generator, with the following relevant files:

app.js:

// ...
var app = express();

//Set up mongoose connection
var mongoose = require('mongoose');
var mongoDB = 'mongodb+srv://username:[email protected]/test?retryWrites=true&w=majority';
mongoose.connect(mongoDB, { useNewUrlParser: true });
var db = mongoose.connection;
db.on('error', console.error.bind(console, 'MongoDB connection error:'));
// ...

index.js:

var express = require('express');
var router = express.Router();
var multer = require("multer");
var fs = require("fs");
var upload = multer({ dest: 'uploads/' })
var Image = require('../models/image');

// GET for image form
router.get("/image/create", function(req, res, next) {
    res.render("create_image", {title: "Create Image"});
});

// Uploading image to mongoDB Atlas
router.post("/image/create", upload.single("image"), function(req, res, next) {
    var image = new Image({
        name: req.body.image_name
    });
    image.img.data = fs.readFileSync(req.file.path);
    image.img.contentType = "image/jpg";
    image.save(function(err) {
        if (err) { return next(err); }
        res.redirect("/");
    });
});

// Show some random image
router.get("/image", function(req, res, next) {
    Image.findOne({}, function(err, image) {
        if (err) { return next(err); }
        res.contentType(image.img.contentType)
        res.send(image.img.data);
    });
});

image.js (Image schema):

var mongoose = require("mongoose");

var Schema = mongoose.Schema;

var ImageSchema = new Schema(
    {
        name: {type: String, required: true, max: 100},
        img: {data: Buffer, contentType: String}
    }
);

module.exports = mongoose.model("Image", ImageSchema);

And finally the form for creating images create_image.pug:

extends layout

block content
    h1= title

    form(action="" method="POST" enctype="multipart/form-data")
        label(for="image_name") Name of Image:
        input#image_name.form-control(type="text" placeholder="Name of image" name="image_name" required="true")
        input(type="file" name="image")
        button(type='submit') Submit

This works sort of fine, in that the image is stored in MongoDB Atlas, but it also stores images locally. Now from a production standpoint this is not a good idea, as the project would get large. However I can't seem to figure out the right way of doing this thing?

Could someone tell me the right way of doing this, so that I only store images on MongoDB Atlas, and not locally? Also possibly tell me if I have this whole thing the wrong way round, and should be doing this in a completely different way?

Upvotes: 4

Views: 4904

Answers (1)

Nisan Coşkun
Nisan Coşkun

Reputation: 561

If you don't want to store images locally, use MemoryStorage as Multer Storage.

var storage = multer.memoryStorage()
var upload = multer({ storage: storage })

When using memory storage, the file info will contain a field called buffer that contains the entire file. So you don't have to call fs.readFileSync. You can access buffer with req.file.image.buffer and assign image data;

image.img.data = req.file.image.buffer;

Upvotes: 5

Related Questions