Search code examples
javascriptnode.jsexpressmongoosebusboy

How to retrieve path of image from mongoDB using Nodejs


I have uploaded the image in to a local directory using Busboy and passed the path of the image to the MongoDB using Mongoose but now I unable to retrieve the path to display the image in my ejs view. I'm new to this nodejs. Please help me to display the image.

Thank you Very much in Advance :)

var express = require('express');    //Express Web Server
var busboy = require('connect-busboy'); //middleware for form/file upload
var path = require('path');     //used for file path
var fs = require('fs-extra');       //File System - for file manipulation
var mongoose = require('mongoose');
var mongoClient = require('mongodb').mongoClient;
var objectId = require('mongodb').ObjectId;
var app = express();
app.use(busboy());
app.use(express.static(path.join(__dirname, 'public')));
mongoose.Promise = global.Promise;

mongoose.connect('mongodb://localhost:27017/postname');
/* ==========================================================
Create a Route (/upload) to handle the Form submission
(handle POST requests to /upload)
Express v4  Route definition
============================================================ */
app.set('view engine','ejs');
 app.use(express.static(__dirname + '/public'));

var nameSchema = mongoose.Schema({
  newfile: Object,
  path: String
});

var compileSchema = mongoose.model('foods', nameSchema);
app.get('/', function(req, res, next) {
  res.render('index',{'title': 'New post app'});
});
app.route('/')
    .post(function (req, res, next) {
        var fstream;
        req.pipe(req.busboy);
        req.busboy.on('file', function (fieldname, file, filename) {
            console.log("Uploading: " + filename);
            //Path where image will be uploaded
            fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
            var dirname = path.join(__dirname + '/public/uploads/' + filename);
            file.pipe(fstream);
            //mongo save
            var paths = new compileSchema({newfile : dirname, passReqToCallback: true});
                paths.save(function(err){
                    if(err)  throw err;
                    compileSchema.find({newfile: dirname}, (err, result) =>{
                      console.log();
                      return result;
                    });
              });
            fstream.on('close', function () {
                console.log("Upload Finished of " + filename);
              //where to go next
              res.redirect('/profile');
            });
        });
    });
    app.get('/profile', (req, res)=>{
      res.render('profile',{photo: req.result});
    });
var server = app.listen(3030, function() {
    console.log('Listening on port %d', server.address().port);
});

My Ejs file is :

<img src='<%= photo.newfile %>' >

Solution

  • This is the typical process of writing and reading from Mongodb using Mongoose. I have not checked whether your streaming and other things work fine but the db workflow would be better this way.

    var express = require('express');    //Express Web Server
    var busboy = require('connect-busboy'); //middleware for form/file upload
    var path = require('path');     //used for file path
    var fs = require('fs-extra');       //File System - for file manipulation
    var mongoose = require('mongoose');
    var mongoClient = require('mongodb').mongoClient;
    var objectId = require('mongodb').ObjectId;
    var app = express();
    app.use(busboy());
    app.use(express.static(path.join(__dirname, 'public')));
    mongoose.Promise = global.Promise;
    
    mongoose.connect('mongodb://localhost:27017/postname');
    /* ==========================================================
    Create a Route (/upload) to handle the Form submission
    (handle POST requests to /upload)
    Express v4  Route definition
    ============================================================ */
    app.set('view engine','ejs');
    app.use(express.static(__dirname + '/public'));
    
    //You can import your schema like this
    const Name = require('./name');
    
    var compileSchema = mongoose.model('foods', nameSchema);
    app.get('/', function(req, res, next) {
        res.render('index',{'title': 'New post app'});
    });
    
    //I have changed your route since it seems to be clashing with the above
    app.post('/save' ,function (req, res, next) {
            var fstream;
            req.pipe(req.busboy);
            req.busboy.on('file', function (fieldname, file, filename) {
                console.log("Uploading: " + filename);
                //Path where image will be uploaded
                fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
                file.pipe(fstream);
                var dirname = path.join(__dirname + '/public/uploads/' + filename);
                //mongo save
    
                fstream.on('close', function () {
                    //You can either save to mongodb after streaming closes or while it is streaming but in this case I will do it after.
                    console.log("Upload Finished of " + filename);
                    //where to go next
    
                    //Declare your schema object here
                    let name = new Name({
                        newfile:'Whatever you want to store here',
                        path: path
                    });
    
                    //Save your declared schema like this
                    name.save((err) => {
                        if(err) throw err;
    
                        console.log(`saved : ${name}`);
    
                        //When you redirect here, it will go to /profile route
                        res.redirect('/profile');
                    });
                });
            });
        });
    app.get('/profile', (req, res)=>{
    
        //You must retrieve from mongodb your object here if this is where you want the object to be
    
        //{} empty query will find all objects in the table
        Name.find({}, (err, result) => {
            if(err) throw err;
            //after everything was found, send it to front end
    
            res.render('profile',{
                photo: req.result,
                //Now your 'compileSchema' object is available at front end as 'result' object
                result:result
            });
        });
    });
    
    var server = app.listen(3030, function() {
        console.log('Listening on port %d', server.address().port);
    });
    

    name.js (create one schema js file for each table you will be working with)

    let mongoose = require('mongoose');
    let Schema = mongoose.Schema;
    
    let compileSchema = new Schema({
        newfile: Object,
        path: String
    });
    
    let Compile = mongoose.model('Compiles', compileSchema);
    
    module.exports = Compile;
    

    Check first that you are receiving and streaming file correctly. If you are, it must work fine. Also, I don't know why you want to save a newfile:object field but all you really need to do is save the path to the image file then retrieve it where you need to use the image and use the path as the <img src='path'> Refer to the comments.