Search code examples
node.jsexpressmongoosemulter

Validate in Multer before upload


Im trying to validate if the idProject that I receive is an ObjectId or if it exists in my db before upload the file with Multer. But it saves the file and then validate.

I've tried put in the index like app.post('/file', ()=>) and it works but I want to keep it in .controller.js and .route.js

  • index.js

const storage = multer.diskStorage({
    destination: path.resolve('./uploads'),
    filename: (req, file, cb, filename) => {
        cb(null, uuid() + path.extname(file.originalname));
    }
});
app.use(multer({storage: storage}).single('file'));

  • project.controller.js

projectCtrl.addFileToProject = async (req, res) => {
    const { id } = req.params;
    await Project.findById(id)
        .then((project) => {
            if(project === null){
                res.json({
                    status: 'Fail to Add File 1'
                });
            }
            else{
                fileCtrl.uploadFile(req, async (cb) => {
                    await Project.findByIdAndUpdate(id, {$addToSet: {files: cb}})
                });
                res.json({
                    status: 'File Added to Project'
                });
            }
        })
        .catch(() => {
            res.json({
                status: 'Fail to Add File 2'
            });
        });
};

  • file.controller.js
    fileCtrl.uploadFile = async (data, cb) => {
    var now = moment();
    const { size } = data.file;
    const { mimetype } = data.file;
    var icon;
    if (mimetype === mime.lookup('.pdf')) {
        icon = 'pdfIcon';
    }
    else if (mimetype === mime.lookup('.doc')) {
        icon = 'docIcon';
    }
    else if (mimetype === mime.lookup('.docx')) {
        icon = 'docIcon';
    }
    else if (mimetype === mime.lookup('.xls')) {
        icon = 'xlsIcon';
    }
    else if (mimetype === mime.lookup('.xlsx')) {
        icon = 'xlsIcon';
    }
    else if (mimetype === mime.lookup('.ppt')) {
        icon = 'pptIcon';
    }
    else if (mimetype === mime.lookup('.pptx')) {
        icon = 'pptIcon';
    }
    else if (mimetype === mime.lookup('.jpg')) {
        icon = 'jpgIcon';
    }
    else if (mimetype === mime.lookup('.png')) {
        icon = 'pngIcon';
    }
    else if (mimetype === mime.lookup('.txt')) {
        icon = 'txtIcon';
    }
    else if (mimetype === mime.lookup('.zip')) {
        icon = 'zipIcon';
    }
    else {
        icon = 'fileIcon';
    }
    var decimals=2;
    if(size == 0) return '0 Bytes';
    var k = 1024,
    dm = decimals <= 0 ? 0 : decimals || 2,
    sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
    i = Math.floor(Math.log(size) / Math.log(k));
    var fileSize = parseFloat((size / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
    const file = new File();
    file.filename = data.file.filename;
    file.author = data.body.author;
    file.path = '/uploads/' + data.file.filename;
    file.originalname = data.file.originalname;
    file.icon = icon;
    file.size = fileSize;
    file.created_at = now;
    await file.save();
    cb(file._id);
    };

Solution

  • With multer, you can't really control upload dynamically. However, what you can do is upload it in a temp folder, and then check if the id exists. If it exists in your database, you can move the file into another folder, otherwise, delete that file