'Generate destination path before file upload - multer

Trying to make a folder before uploading a file to it. However, there is a problem if I do not update the server on the node when I try to download the file again, it is added to the already created folder. If I update the server, it creates a new folder and uploads it as needed. Please see the code, how can I improve it?

const db = require('../db');
const fs = require('fs');
const path = require('path');
const uuidv1 = require('uuid/v1');
const multer = require('multer');

console.log(uuidv1())
let storage = multer.diskStorage({
  destination: `./uploads/${uuidv1()}`,
  filename: (req, file, cb) => {
    cb(null, 'test1' + '-' + Date.now() + '.' + path.extname(file.originalname));
  }
});

let upload = multer({storage});

module.exports = (router) => {

  router.get('/get', (req, res) => {
    db.connect.query('SELECT * FROM habalka',
      {type: db.sequelize.QueryTypes.SELECT}
    ).then(result => {
      res.json(result);
    })
  });

  router.post('/post', upload.any(), (req, res) => {
    res.json('test');


  });

  return router;
};


Solution 1:[1]

Your issue is that when You start Your app it generates new uuid (once - at app startup) and passes as string to diskStorage method.

But You want to generate that path every-time when You upload a file.


So here is the solution:

Multer has feature to dynamically generate both destination path and filename.

So You've to pass a function that will generate path and return it in callback.

Example after reading this manual:

let storage = multer.diskStorage({

  // pass function that will generate destination path
  destination: (req, file, cb) => {

    // initial upload path
    let destination = path.join(__dirname, 'uploads'); // ./uploads/

    // if user logged in and You store user object in session
    if (req.session && req.session.user && req.session.user.id) {
      destination = path.join(destination, 'users', req.session.user.id, uuidv1()); // ./uploads/users/8/generated-uuid-here/
    }
    else {
      destination = path.join(destination, 'files', uuidv1()); // ./uploads/files/generated-uuid-here/
    }

    cb(
      null, 
      destination
    );
  },

  // pass function that may generate unique filename if needed
  filename: (req, file, cb) => {
    cb(
      null, 
      Date.now() + '.' + path.extname(file.originalname)
    );
  }

});

Solution 2:[2]

My final code is here and it works !Thanks

const db = require('../db');
const fs = require('fs');
const uuid = require('uuid');
const path = require('path');
const multer = require('multer');
const shell = require('shelljs');


console.log(uuid())

let storage = multer.diskStorage({

  // pass function that will generate destination path
  destination: (req, file, cb) => {
    // initial upload path
    let destination = path.join(__dirname, '../uploads'); // ./uploads/

    let id = uuid();
    shell.mkdir('-p', './uploads/' + id);
    destination = path.join(destination, '', id); // ./uploads/files/generated-uuid-here/
    console.log('dest', destination)

    cb(
      null,
      destination
    );
  },

  // pass function that may generate unique filename if needed
  filename: (req, file, cb) => {
   let ext = file.originalname.substring(file.originalname.lastIndexOf('.'), file.originalname.length);
  callback(null,file.originalname.split('.').slice(0,-1).join('.') + '-'+Date.now() +ext);
  }

});

var upload = multer({storage: storage})

module.exports = (router) => {

  router.get('/get', (req, res) => {
    db.connect.query('SELECT * FROM habalka',
      {type: db.sequelize.QueryTypes.SELECT}
    ).then(result => {
      res.json(result);
    })
  });

 app.post('/uploads', function (req, res) {
upload(req, res, function (err) {
  if (err) {
    console.log(err);
    return res.end("Something went wrong!");
  }else{
    
  let ext = req.file.originalname.substring(req.file.originalname.lastIndexOf('.'), req.file.originalname.length);
    var files='./uploads/'+req.file.originalname.split('.').slice(0 ,-1).join('.')+'-'+Date.now()+ext
    console.log(req.file.originalname);
    collection.insertOne({files},function(err,result){
      if(err){
           console.log("Something is Wrong");
      }else{
        
        res.json(result._id);
        console.log(result);
      }
    })
   }
});

})

  return router;
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Rahul Pawar