Search code examples
node.jsmongodbexpressmongoosebusboy

Getting all the images uploaded from MongoDB


I made a upload image to a document and saved the path to the MongoDB , While retrieving the Image, It is showing only the current image which is being uploaded. I want to show all the images which is uploaded to the database. Please help me to display all the images from the Data base. Thank you 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 handlebars = require('handlebars');
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', 'hbs');
app.set('views', path.join(__dirname, 'views'));

app.use(express.static(__dirname + '/public'));

//You can import your schema like this
const Name = require('./name');

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, done){
    console.log("Uploading" + filename);
    //path where the file is being uploaded
    fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename);
    var dirname = path.join( 'uploads/' + filename);
    file.pipe(fstream);
    fstream.on('close', function(){
      console.log("Upload Success" + filename);

      let name = new Name({
        path: dirname
      });
      name.save((err)=>{
        if(err) throw err;
        console.log(`saved : ${name}`);
        res.redirect('/profile');
        call(dirname);
      });
    });
  });
});
function call(dirname){
Name.findOne({path: dirname}, (err, result) =>{
    if(err) throw err;
    var imgpath = result.path;
    console.log("Saved check" + imgpath);
    app.get('/profile', (req, res) =>{
      res.render('profile',{
        photo: req.result,
        result : imgpath
      });
    });
  });
}


var server = app.listen(3030, function() {
    console.log('Listening on port %d', server.address().port);
});

My name.js file Mongoose Schema

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

let compileSchema = new Schema({
    path: String
});

let Compile = mongoose.model('Compiles', compileSchema);

module.exports = Compile;

Views File to display the image

<html>
  <head>
    <title>User Profile</title>
  </head>
  <body>
    <h1>Welcome</h1>{{result}}<br><br>
    <img src="{{result}}" height="180" width="250">
  </body>
</html>

Solution

  • You are using findOne which only retrieves one object from the database. So if you want to retrieve all the images your code should be something like this :

    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 handlebars = require('handlebars')
    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', 'hbs')
    app.set('views', path.join(__dirname, 'views'))
    
    app.use(express.static(__dirname + '/public'))
    
    // You can import your schema like this
    const Name = require('./name')
    
    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, done) {
        console.log('Uploading' + filename)
        // path where the file is being uploaded
        fstream = fs.createWriteStream(__dirname + '/public/uploads/' + filename)
        var dirname = path.join( 'uploads/' + filename)
        file.pipe(fstream)
        fstream.on('close', function () {
          console.log('Upload Success' + filename)
    
          let name = new Name({
            path: dirname
          })
          name.save((err) => {
            if (err) throw err
            console.log(`saved : ${name}`)
            res.redirect('/profile')
          // removed call(), no need for it
          })
        })
      })
    })
    
    app.get('/profile', (req, res) => {
      // get all documents in the db by using find with no conditions
      Name.find({}, (err, results) => {
        if (err) throw err
        var images = []
        for (var result of results) {
          images.push(result.path)
        }
        res.render('profile', {
          images: images
        })
      })
    })
    
    var server = app.listen(3030, function () {
      console.log('Listening on port %d', server.address().port)
    })
    

    And in the views you should loop through the images to display them, i believe you are using handlebars so the view should be something like this :

    <html>
      <head>
        <title>User Profile</title>
      </head>
      <body>
        <h1>Welcome</h1>
        {{#each images}}
          <img src="{{this}}" height="180" width="250">
        {{/each}}
      </body>
    </html>