Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
store/display an image in mongodb using mongoose/express
/**
* Module dependencies
*/
var express = require('express');
var fs = require('fs');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// img path
var imgPath = '/path/to/some/img.png';
// connect to mongo
mongoose.connect('localhost', 'testing_storeImg');
// example schema
var schema = new Schema({
img: { data: Buffer, contentType: String }
});
// our model
var A = mongoose.model('A', schema);
mongoose.connection.on('open', function () {
console.error('mongo is open');
// empty the collection
A.remove(function (err) {
if (err) throw err;
console.error('removed old docs');
// store an img in binary in mongo
var a = new A;
a.img.data = fs.readFileSync(imgPath);
a.img.contentType = 'image/png';
a.save(function (err, a) {
if (err) throw err;
console.error('saved img to mongo');
// start a demo server
var server = express.createServer();
server.get('/', function (req, res, next) {
A.findById(a, function (err, doc) {
if (err) return next(err);
res.contentType(doc.img.contentType);
res.send(doc.img.data);
});
});
server.on('close', function () {
console.error('dropping db');
mongoose.connection.db.dropDatabase(function () {
console.error('closing db connection');
mongoose.connection.close();
});
});
server.listen(3333, function (err) {
var address = server.address();
console.error('server listening on http://%s:%d', address.address, address.port);
console.error('press CTRL+C to exit');
});
process.on('SIGINT', function () {
server.close();
});
});
});
});
@nascos

This comment has been minimized.

Copy link

nascos commented Nov 29, 2012

thx

var address = server.address();
console.error('server listening on http://%s:%d', address.address, address.port);
delete this code

it run perfect

@kb19

This comment has been minimized.

Copy link

kb19 commented Mar 22, 2013

Thanks for this example, I was able to successfully adapt it to my needs. An odd behaviour I ran into was that after I saved the file, I wasn't able to directly send the file back in the A.save callback. I'm assuming that I'm missing something here but am not sure what.

@cutesquirrel

This comment has been minimized.

Copy link

cutesquirrel commented Aug 26, 2014

Thx Aaron.

Here, I add the way to download the image from an URL and not locally :

    // Loads mikeal/request Node.js library.
    var request = require('request');

    // Specify the encoding (the important is to keep the same when creating the buffer, after)
    // If you only give the URL, it brakes the downloaded data, I didn't found an other way to do it.
    request({
          url: 'http://www.cedynamix.fr/wp-content/uploads/Tux/Tux-G2.png',
          encoding: 'binary'
        }, function(error, response, body) {
          if (!error && response.statusCode === 200) {
             body = new Buffer(body, 'binary');

             // Here "body" can be affected to the "a.img.data"
             // var a = new A;
             // a.img.data = body;
             // ....
          }
     });
@stonnedd

This comment has been minimized.

Copy link

stonnedd commented Sep 19, 2014

hi im new in mongoose so i have a basic questions i already save some image with your code but how can i display the image in ejs view
my code:

//  schema************************************************/

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var productSchema   = new Schema({

    idProduct: {
        type: mongoose.Schema.Types.ObjectId,
        index: true
    },
    category: {type: String},
    product: {type: String},
    model: {type: String},
    brand: {type: String},
    size: {type: String},
    price: {type: String},
    description: {type: String},
    color : {type: String},
    quantity: {type: Number},
    img1: { data: Buffer, contentType: String },
    uploadDate: {type: Date, default: Date.now}
});
module.exports = productSchema;

// model *****************************************/
var mongoose = require('mongoose');
var ProductSchema = require('../schemas/productSchema.js');

var Product = mongoose.model('Product',ProductSchema);
module.exports = Product;

// adding the data ****************************************/

var imgPath = './public/images/test.jpg';

var product = new productModel({
    category: 'something',
    product: 'something',
    model: 'something',
    brand: 'something',
    size:  'something',
    price: 'something',
    description :'something',
    color : 'something'
});

product.img1.data = fs.readFileSync(imgPath);
product.img1.contentType = 'jpg';
product.save(function(err, products) {
    if (err) return console.error(err);
    console.dir(products);

// routes/index.js **********************/

router.get('/', function(req, res) {
    productModel.find({}, function(err,products){
    res.render('index',{ products: products});
     });
});

// view  index.ejs*************/

<!DOCTYPE html>
<html>

<a href = "index">
    <% products.forEach(function(product){ %>
        <img src=<%=product.img1%> >
    <% }) %>
    <span>test</span>
</a>

</html>

but there is no image in the view just the box of the image, some idea or what im doing wrong?

@nilasissen

This comment has been minimized.

Copy link

nilasissen commented Mar 17, 2015

what happens when the image is coming as in json(base64) and i want to store it in a file rather than storing in database

@ziaulain

This comment has been minimized.

Copy link

ziaulain commented May 22, 2015

Get Image from db and display on front end...
Server side:

    app.get('/api/getcake', function(req, res) {
        console.log("Get cake function");
        model.find(function (err, doc) {
            if (err) return next(err);
        var base64 = (doc[0].img.data.toString('base64'));
         res.send(base64);        
        });
    });

Client Side:

$scope.GetCake = function() {
$http.get('/api/getcake')
.success(function(doc) {
console.log(doc);
$scope.imgsource=doc;
})
.error(function(data) {
console.log('Error: ' + data);
});
};

view side:

@suederade

This comment has been minimized.

Copy link

suederade commented Aug 12, 2015

This sends back weirdly encoded images and not actually images. Can't seem to get them to display actual images.

@vaishnavirsh

This comment has been minimized.

Copy link

vaishnavirsh commented Oct 20, 2015

How to get more than one image from mongodb where all the images either in same format or in different format?? Images are saved as buffer in mongodb as given in above example

@HarrisonA

This comment has been minimized.

Copy link

HarrisonA commented Jan 28, 2016

This was very helpful. Here's some links I used to adapt it to my server and front end needs ( Express/Node and Angular):

Uploading images with Angular:
https://github.com/danialfarid/ng-file-upload#usage

Coding the angular controller and its HTML to send one file at a time:
http://jsfiddle.net/danialfarid/0mz6ff9o/135/

I needed to use middleware with my server in order to receive the image:
// http://stackoverflow.com/questions/24610996/how-to-get-uploaded-file-in-node-js-express-app-using-angular-file-upload
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

When getting the image back from the database you may need to convert the image array buffer to a base 64 string before displaying it in HTML:
http://stackoverflow.com/questions/9267899/arraybuffer-to-base64-encoded-string

@forl

This comment has been minimized.

Copy link

forl commented Apr 20, 2016

nice!

@thedamphair

This comment has been minimized.

Copy link

thedamphair commented May 20, 2016

I have a doubt, How can I get more than one image?

@MatthewKosloski

This comment has been minimized.

Copy link

MatthewKosloski commented Aug 13, 2016

If I have a file with data that looks like the following, how can I turn it into a .jpg again? I know what the encoding and mime type is.
Alt text

@y4my4my4m

This comment has been minimized.

Copy link

y4my4my4m commented Sep 28, 2016

@MatthewKosloski

What about

var b64string = /* code */;
var buf = Buffer.from(b64string, 'base64'); // output var
@kathar1223

This comment has been minimized.

@manisjosjs

This comment has been minimized.

Copy link

manisjosjs commented Dec 8, 2016

@kathar1223
Hey I did follow up your blog, And have to say, You have saved my day - but I want more help. I am able to upload image using the instructions provided but I do not know How to proceed with displaying the image on webpage or storing its location path into mongodb through moongoose.

@iKvod

This comment has been minimized.

Copy link

iKvod commented Dec 15, 2016

amazing

@UtsavAgrawal23

This comment has been minimized.

Copy link

UtsavAgrawal23 commented Dec 29, 2016

I am able to save single image, but how we can save more than one images in mongodb and retrieve back

@ghost

This comment has been minimized.

Copy link

ghost commented Feb 22, 2017

UtsavAgrawal23 You could store an array of objects in the image field in your schema:-

var imageSchema = new Schema({
img: { data: Buffer, contentType: String }
});

var productSchema = new Schema({
img: [imageSchema];
});

@socket-var

This comment has been minimized.

Copy link

socket-var commented Feb 23, 2017

Isn't readfilesync synchronous ? It shouldn't be used in web apps right ? If the image I huge then the entire IO is blocked right ?

@jasonwr

This comment has been minimized.

Copy link

jasonwr commented Mar 3, 2017

@saketh-bobby regardless of readfilesync this whole approach is only beneficial if images are 16Mb or less because of Mongo's retrieve restrictions. A better approach would be GridFS, but this approach also works well for smaller images, such as resized PNG's. I'll try to get a demo out later.

@lahong

This comment has been minimized.

Copy link

lahong commented Mar 8, 2017

@jsonwr a demo with this would be greatly appreciated thanks in advance

@Ainafidy

This comment has been minimized.

Copy link

Ainafidy commented Apr 19, 2017

Hi,can you help me in this code:

photo.controller--------------------------------------------

var mongoose = require('mongoose');
var PhotoModel = mongoose.model('Photos');
var fs =require('fs');

exports.addPhoto = function (req, res) {
var path='./Desktop/ExoInterfaceAPP/ic_friends.png'; //req.body.photo
if(fs.existsSync(path)) {
var photo = new PhotoModel();
photo._userid = req.body._userid;
photo.photo.data = fs.readFileSync(path);
photo.photo.contentType = 'image/png';
photo.as_profil = true;
photo.save((err, saved) => {
if (err) {
res.status(500).send(err);
} else {
console.log('sary ok');
res.json({
//data: saved,
status: true,
message: 'photo add success'
});
}
});
}

}

because my image in this path is not upload, my objectif is to upload the photo intruduct in "req.body.photo",
help me please

@kaushikpatel369

This comment has been minimized.

Copy link

kaushikpatel369 commented May 9, 2017

i want to store images dynamically.
select image using file select and then store

@TarunKashyap18

This comment has been minimized.

Copy link

TarunKashyap18 commented Jul 29, 2017

@octaviansoldea

This comment has been minimized.

Copy link

octaviansoldea commented Aug 7, 2017

At line 43, instead of

  var server = express.createServer();

I would rather use

  var server = express();

. In this context, see, also https://stackoverflow.com/questions/13499010/nodejs-express-launching-my-app-express-createserver-is-deprecated.

@ashrafSeven

This comment has been minimized.

Copy link

ashrafSeven commented Aug 10, 2017

Hi, I am using nodejs=mongodb. for the image upload, I want to give max size 5MB or 6MB. How can I do that? Can anyone tel me please..

here is my schema. for the coverImage, it allows max only 40kb size to upload the image but now I want to make it to 5MB.

 const nameSchema = Joi.object().keys({
description: Joi.string(), // .required(),
coverImage: Joi.string().Data: Buffer, // .required(), // ({ scheme: ['http', 'https'] }),
category: Joi.string(),
slug: Joi.string().regex(/^[a-z][a-z0-9-]*$/),
title: Joi.string(), // .required(),
price: Joi.number().integer(),
tag: Joi.object().keys({
    tag_name: Joi.string()
}),
publisher: Joi.object().keys({
    _id: Joi.string().hex().length(24),
    name: Joi.string().required()
}),
// published: Joi.string().isoDate().default(Date.now()),
rating: Joi.number().precision(2),
views: Joi.number().integer(),
hasErrors: Joi.boolean(),
allowSorting: Joi.boolean(),
allowAltered: Joi.boolean(),
choosetemplate: Joi.boolean(),
formErrors: Joi.object().keys({
    title: Joi.string(),
    description: Joi.string()
}),
includeCompleted: Joi.boolean(),
created_at: Joi.date().default(Date()),

});

@TheRobOne

This comment has been minimized.

Copy link

TheRobOne commented Aug 26, 2017

@kathar1223
Your solution doesn't store image in db only path to that image.
Am I right?

@TheRobOne

This comment has been minimized.

Copy link

TheRobOne commented Aug 26, 2017

Output of the db.as.find().pretty() gives very very long string. So do you think it is better to store user details in diffrent collection then its avatar?

@shoaibnoor95

This comment has been minimized.

Copy link

shoaibnoor95 commented Jan 13, 2018

Is there any dependency of it?

@jaggu07

This comment has been minimized.

Copy link

jaggu07 commented Feb 6, 2018

works fine in localhost but fileread is not working in server
`events.js:160
throw er; // Unhandled 'error' event
^

Error: ENOENT: no such file or directory, open 'file:///Users/rda/Desktop/Appointment Booking.png'
at Error (native)
at Object.fs.openSync (fs.js:640:18)
at Object.fs.readFileSync (fs.js:508:33)`

@Goran7777

This comment has been minimized.

Copy link

Goran7777 commented Jun 14, 2018

Seems to me this is one of hardest back-end topics.

@Skycocoo

This comment has been minimized.

Copy link

Skycocoo commented Jul 17, 2018

So the working example to store image to local directory @TarunKashyap18 provided has few things to be noted:

  • to run the project: $ node app.js

  • the localhost its listening to is localhost:8000 instead of localhost:3000 noted in the comment (possibly didnt change much from the blog by @kathar1223.

  • to test the result: first open localhost:8000 to upload a random image; then open http://localhost:8000/images to check the _id of the stored image; to check the image: open http://localhost:8000/picture/(the _id you just checked)


A revised sample with detailed README could be found here

@yasoza

This comment has been minimized.

Copy link

yasoza commented Oct 16, 2018

Thanks a ton. I was searching a way to store files in mongo db for days.

@Arshitabhatt

This comment has been minimized.

Copy link

Arshitabhatt commented Jun 22, 2019

I can't thank you enough.

@BEN00262

This comment has been minimized.

Copy link

BEN00262 commented Aug 22, 2019

thanks for this, it really helped me

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.