1

I have a back end using node.js and a front end using jquery, javascript, ajax and bootstrap. I want to upload an image from front end and save it to the mongoose database. Here the file is loading successfully and image will be in the location called /public/img. But how can I save those image information into the database using an API call.
Below is my code:

Backend Code Node.js, Mongoose

/server.js

var express = require("express"); var multer = require('multer'); var path = require('path'); var mongoose = require('mongoose'); var bodyParser = require('body-parser'); var app = express(); app.appname="photogallery"; //config mongoose app.db = mongoose.createConnection('localhost/'+app.appname); app.db.on('error', console.error.bind(console, 'mongoose connection error: ')); app.db.once('open', function () { //Storage is all good }); //Routes and acl var router = express.Router(); require('./routes')(app, router, passport); var file_url = ''; var storage = multer.diskStorage({ destination: function (req, file, callback) { callback(null, 'public/img/'); }, filename: function (req, file, callback) { callback(null, file.fieldname + '-' + Date.now()); file_url = file.fieldname + '-' + Date.now() + '.' + file.originalname.split('.')[file.originalname.split('.').length -1] callback(null, file_url); } }); var upload = multer({ storage : storage}).single('userPhoto'); app.use(express.static(path.join(__dirname, '/public/'))); app.post('/api/photo',function(req,res){ upload(req,res,function(err) { if(err) { return res.end("Error uploading file."); } // res.end("File is uploaded"); res.json({error_code:0,err_desc:null,file_url:'img/'+file_url}); /*Now I want to save this file_url to image_url using api /api/photoGallery, please help me to save these information to the db */ }); }); //config express app.set('secret','thisshouldnotbeinplaintext'); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(passport.initialize()); app.use(router); app.listen(5050,function(){ console.log("Working on port 5050"); }); 

/api/requests.js

'use strict'; var passport = require('passport'); var app = require('../app'); exports.init = function(pp) { passport = pp; app = pp; return exports; }; exports.root = function(req, res) { res.send("Running"); }; //Add Image Data exports.addData = function(req, res) { var addData = req.app.db.model('Data'); var data = { image_title : req.body.image_title, image_url : "http://localhost:5050/"+req.body.image_url } var query = addData(data); query.save(function(err){ if(err){ console.log(err.toString()); } console.log('Image Saved Successfully'); res.json({ success: true }); }); }; 

/schema/Data.js

'use strict'; exports = module.exports = function(app, mongoose) { var dataSchema = new mongoose.Schema({ image_title : { type: String, unique: true, lowercase: true }, image_url : { type: String, unique: true, lowercase: true } }); app.db.model('Data', dataSchema); }; 

/models.js

'use strict'; module.exports = function(app, mongoose) { //Mongoose Schemas require('./schema/Data')(app, mongoose); }; 

/routes.js

 'use strict'; module.exports = function(app, router, passport) { var requests = require('./api/requests').init(passport); router.get('/', requests.root); router.post('/api/addPhoto/v1', requests.addData); router.get('/api/getPhoto/v1', requests.getPhoto); }; 

e.g Json Will Be like below

{ image_title: exampleImage, image_url: xyzscjnscncsl.exampleImage.png } 

Frontend Code Jquery, JavaScript, Ajax, HTML

/public/index.html

<div class="modal fade" id="myModal" role="dialog"> <div class="modal-dialog"> <!-- Modal content--> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">&times;</button> <h4 class="modal-title">Please Upload Image</h4> </div> <form id="uploadForm" enctype="multipart/form-data" action="/api/photo" method="post"> <div class="modal-body"> <div class="form-group"> <input type="text" class="form-control" id="imagetitle" placeholder="Image Title"> </div> <div class="form-group"> <input type="file" class="form-control" id="input-image" name="userPhoto" accept="image/*"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancle</button> <button type="submit" class="btn btn-default" value="Upload Image" name="submit">Save</button> </div> <span id = "status"></span> </form> </div> </div> </div> 

/public/javascript/image.js

How to save image data from here to the mongoose db using an API call?

$(document).ready(function() { $('#uploadForm').submit(function() { $("#status").empty().text("File is uploading..."); $(this).ajaxSubmit({ error: function(xhr) { status('Error: ' + xhr.status); }, success: function(response) { console.log(response) $("#status").empty().text(response); } }); return false; }); }); 
2
  • I'd just like to say "don't". It's not a good approach to save image data into your database. Database's are capable of, but not optimized for, block storage of large binary chunks. You're better off saving it to some block storage service (e.g. S3) and just putting a URL to it in your db. Commented Feb 12, 2017 at 16:15
  • ok thanks, but is not a solution of my problem. here I donot want to save it in S3. I want to save it in my database.please help me anyone, I am new in these technology. Commented Feb 12, 2017 at 17:58

3 Answers 3

2

I would not recommend that for most projects (as Paul commented), but it's not complicated.

After you get the image file from the client, you read the image data (fs.readFile) and use a buffer to encode it to base64 and save into your DB, this way you will use less space to store the data. Then you decode the base64 data when you need the binaries.

fs.readFile('foo.png', function(err, data) { const base64img = new Buffer(data).toString('base64'); }); 

There are some npm modules that make this a bit simpler, such as base64-img.

Sign up to request clarification or add additional context in comments.

Comments

0

I would recommend that you use busboy instead of multer, because multer saves to disk, and busboy returns a stream that you can pipe to whatever you want(even to mongoDB).

Gridfs-stream is a good module to stream data to your mongoDB using the gridfs feature.

Here is a basic use of them together:

var Busboy = require('busboy'); var gfs = require('gridfs-stream')(mongoose.connection.db, mongoose.mongo) //express middleware: function (req, res) { var busboy = new Busboy({ headers: req.headers, limits: { fileSize: 1024, files: 1 } }); busboy.on('file', function (fieldname, file, filename, encoding, mimetype) { var ws = gfs.createWriteStream({ filename: filename, content_type: mimetype}); ws.on('error', function(err) { console.error(err); res.send(500, err); }); ws.on('finish', () => {/*do something when streaming ends*/}); file.pipe(ws); } busboy.on('error', function(err) { console.error(err); res.send(500, err); }); req.pipe(busboy); } 

3 Comments

here is a link about gridfs: docs.mongodb.com/manual/core/gridfs
thank you, but I want to store the image information in my db through /api/photoGallery, json ({image_title: myImage, image_url: xxxxxmyImage.png}). please see my schema, models, mongo connection, routes . please help me to save these image information into the DB.
You can add metadata to the file in the createWriteStream function, or to follow up with a call to mongoose API in the stream's finish event.
0

/* Here is the solution */

/server.js

var express = require("express"); var multer = require('multer'); var path = require('path'); var passport = require('passport'); var mongoose = require('mongoose'); var bodyParser = require('body-parser'); var app = express(); app.appname="photogallery"; //config mongoose app.db = mongoose.createConnection('localhost/'+app.appname); app.db.on('error', console.error.bind(console, 'mongoose connection error: ')); app.db.once('open', function () { }); //config data models require('./models')(app, mongoose); //Routes and acl var router = express.Router(); require('./routes')(app, router, passport); /* Image Logic */ var file_url = ''; var storage = multer.diskStorage({ destination: function (req, file, callback) { callback(null, 'public/img/'); }, filename: function (req, file, callback) { callback(null, file.fieldname + '-' + Date.now()); file_url = file.fieldname + '-' + Date.now() + '.' + file.originalname.split('.')[file.originalname.split('.').length -1]; callback(null, file_url); } }); var upload = multer({ storage : storage}).single('userPhoto'); app.use(express.static(path.join(__dirname, '/public/'))); app.post('/api/photo',function(req,res){ upload(req,res,function(err) { if(err) { return res.end("Error uploading file."); } //res.end("File is uploaded"); //console.log("file_url", file_url); res.json({error_code:0,err_desc:null, file_url:'img/'+file_url}); }); }); //config express app.set('secret','thisshouldnotbeinplaintext'); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()); app.use(passport.initialize()); app.use(router); app.listen(5050,function(){ console.log("Working on port 5050"); }); 

/api/requests.js

 'use strict'; var jwt = require('jsonwebtoken'); var passport = require('passport'); exports.init = function(pp) { passport = pp; return exports; }; exports.root = function(req, res) { res.send("Running"); }; /* Save Image Data Function */ exports.addData = function(req, res) { var addData = req.app.db.model('Data'); var data = { img_title : req.body.img_title, img_url : "http://localhost:5050/"+req.body.img_url } var query = addData(data); query.save(function (err, data) { if (err) { console.log(err.toString()); } else { console.log('Image saved Successfully'); res.json(data); } }); }; /* Get Image Data Function */ exports.getPhoto = function(req, res) { var getPhoto = req.app.db.model("Data"); var query = getPhoto.find(function(err, data){ if(err) { console.log("Not Found"); } else { res.json({'data': data}); } }); }; 

/schema/Data.js

'use strict'; module.exports = function(app, mongoose) { var dataSchema = new mongoose.Schema({ img_title : { type: String, default: '' }, img_url : { type: String, default: '' } }); app.db.model('Data', dataSchema); }; 

/models.js

'use strict'; module.exports = function(app, mongoose) { //Mongoose Schemas require('./schema/Data')(app, mongoose); } 

/routes.js

'use strict'; module.exports = function(app, router, passport) { var requests = require('./api/requests').init(passport); router.get('/', requests.root); router.post('/api/addPhoto/v1', requests.addData); router.get('/api/getPhoto/v1', requests.getPhoto); }; 

/public/index.html

<div class="modal fade" id="myModal" role="dialog"> <div class="modal-dialog"> <!-- Modal content--> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal">&times;</button> <h4 class="modal-title">Please Upload Image</h4> </div> <form id="uploadForm" enctype="multipart/form-data" action="/api/photo" method="post"> <div class="modal-body"> <div class="form-group"> <input type="text" class="form-control" id="imagetitle" placeholder="Image Title"> </div> <div class="form-group"> <input type="file" class="form-control" id="input-image" name="userPhoto" accept="image/*"> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-default" data-dismiss="modal">Cancle</button> <button type="submit" class="btn btn-default" value="Upload Image" name="submit">Save</button> </div> <span id = "status"></span> </form> </div> </div> </div> 

/public/javascript/image.js

/* How to save image data from Frontend to mongoose using api call */

$(document).ready(function() { $('#uploadForm').submit(function() { $("#status").empty().text("File is uploading..."); var imageTitle = $("#imagetitle").val(); $(this).ajaxSubmit({ error: function(xhr) { status('Error: ' + xhr.status); }, success: function(response) { var localFile = response.file_url; $.ajax({ url: "/api/addPhoto/v1", data: { img_title: imageTitle, img_url: localFile }, method: 'post', dataType: 'json', success: function(data) { var html = ""; html+= "<div class='col-md-3 col-md-offset-1'>"; html+= "<div class='img-box imgClass'>"; html+= "<img src='"+data.img_url+"'>"; html+= "</div> </div>"; $('.myimage').append(html); $('#myModal').modal('hide'); }, error: function(xhr, status) { alert("Sorry, there was a problem!"); } }); } }); return false; }); }); $(function(){ $.get("/api/getPhoto/v1", function(response) { //console.log(response.data.length); var html = ""; for(var i = 0; i< response.data.length ; i++){ html+= "<div class='col-md-3 col-md-offset-1'>"; html+= "<div class='img-box imgClass'>"; html+= "<img src='"+response.data[i].img_url+"'>"; html+= "</div> </div>" } $('.myimage').html(html); }); }); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.