Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nodejs save uploaded file

I have an application and in that application, I want to use some file upload mechanism.

My requirement is:

Once the file is uploaded, its name will be changed to something unique, like uuid4(). I will store this name in the database later.

I have written something like that, however I have a couple of questions:

const multer = require('multer');
const upload = multer();
router.post('/', middleware.checkToken, upload.single('file'), (req,res,next)=>{

    // key:
    // file : "Insert File Here"

    console.log("req:");
    console.log(req.file);
    const str = req.file.originalname
    var filename = str.substring(0,str.lastIndexOf('.'));
    // I will use filename and uuid for storing it in the database
    // I will generate unique uuid for the document and store the document
    // with that name
    var extension = str.substring(str.lastIndexOf('.') + 1, str.length);

    // HERE!

    res.status(200).json();

})

I have seen examples of storing it in the diskStorage:

var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, '/tmp/my-uploads')
    },
    filename: function (req, file, cb) {
        cb(null, file.fieldname + '-' + Date.now())
  }
})

var upload = multer({ storage: storage })

However, as far as I understood, this is a configuration outside of the API call. Meaning that I cannot modify it every time I call this API. I want to assign different names to the file, and I need that name(uuid) to save that name in the database.

How can I preserve such functionality?

like image 228
q723240 Avatar asked Sep 05 '26 10:09

q723240


1 Answers

Thanks to @Rashomon and @Eimran Hossain Eimon, I have solved the issue. In case of anyone wonders the solution, here it is:

const multer = require('multer');
var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        // the file is saved to here
        cb(null, '/PATH/TO/FILE')
    },
    filename: function (req, file, cb) {
        // the filename field is added or altered here once the file is uploaded
        cb(null, uuidv4() + '.xlsx')
    }
})
var upload = multer({ storage: storage })


router.post('/', middleware.checkToken, upload.single('file'), (req,res,next)=>{
    // the file is taken from multi-form and the key of the form must be "file"

    // visible name of the file, which is the original, uploaded name of the file
    const name = req.file.originalname;

    // name of the file to be stored, which contains unique uuidv4
    const fileName = req.file.filename;
    // get rid of the extension of the file ".xlsx"
    const file_id = fileName.substring(0, fileName.lastIndexOf('.'));

    // TODO
    // Right now, only xlsx is supported
    const type = "xlsx";

    const myObject = new DatabaseObject({
        _id : new mongoose.Types.ObjectId(),
        file_id: file_id,
        name : name,
        type: "xlsx"
    })

    myObject .save()
    .then(savedObject=>{
        // return some meaningful response
    }).catch(err=>{
        // return error response
    })
})

This solves my current issue. Thanks for helping. For future improvements, I'll add error case for:

  • In case uuidv4 returns an id which already exists(I believe it is highly unlikely since the object contains some timestamp data), rerun the renaming function.

  • In case there is an error in saving to the database, I should delete the uploaded file to avoid future conflicts.

If you have solutions for those problems too, I'm much appreciated.

like image 184
q723240 Avatar answered Sep 08 '26 06:09

q723240



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!