Uploading multiple files with multer, but from different fields?

Using Multer Upload Files From Two Fields of Separate Forms on Different Pages In this example I have two fields - resume and image. Resume in one form and Image in other. Both are on separate pages. First import dependencies

const path = require('path'); // for getting file extension
const multer = require('multer'); // for uploading files
const uuidv4 = require('uuidv4'); // for naming files with random characters

Define fileStorage and fileFilter:

const fileStorage = multer.diskStorage({
  destination: (req, file, cb) => { // setting destination of uploading files        
    if (file.fieldname === "resume") { // if uploading resume
      cb(null, 'resumes');
    } else { // else uploading image
      cb(null, 'images');
    }
  },
  filename: (req, file, cb) => { // naming file
    cb(null, file.fieldname+"-"+uuidv4()+path.extname(file.originalname));
  }
});

const fileFilter = (req, file, cb) => {
  if (file.fieldname === "resume") { // if uploading resume
    if (
      file.mimetype === 'application/pdf' ||
      file.mimetype === 'application/msword' ||
      file.mimetype === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    ) { // check file type to be pdf, doc, or docx
      cb(null, true);
    } else {
      cb(null, false); // else fails
    }
  } else { // else uploading image
    if (
      file.mimetype === 'image/png' ||
      file.mimetype === 'image/jpg' ||
      file.mimetype === 'image/jpeg'
    ) { // check file type to be png, jpeg, or jpg
      cb(null, true);
    } else {
      cb(null, false); // else fails
    }
  }
};

Middleware for multer

app.use(
  multer(
    { 
      storage: fileStorage, 
      limits:
        { 
          fileSize:'2mb' 
        }, 
      fileFilter: fileFilter 
    }
  ).fields(
    [
      { 
        name: 'resume', 
        maxCount: 1 
      }, 
      { 
        name: 'image', 
        maxCount: 1 
      }
    ]
  )
);

And then call your routes. You may need to add csrf protection or authentication along with this for security. But this should work fine.


If you want to upload multiple files/images from the same form, I have used the below code and it works fine. The path of the image is stored in the database; I will skip the database path and go straight to the upload function and how the fields are passed to the save function.

    const path = require('path');
    const multer = require('multer');
    const storage = multer.diskStorage({
        destination: (req, file, cb) => {
           if (file.fieldname === "profile") {
               cb(null, './uploads/profiles/')
           }
           else if (file.fieldname === "natid") {
               cb(null, './uploads/ids/');
           }
           else if (file.fieldname === "certificate") {
               cb(null, './uploads/certificates/')
           }
        },
        filename:(req,file,cb)=>{
            if (file.fieldname === "profile") {
                cb(null, file.fieldname+Date.now()+path.extname(file.originalname));
            }
          else if (file.fieldname === "natid") {
            cb(null, file.fieldname+Date.now()+path.extname(file.originalname));
          }
          else if (file.fieldname === "certificate") {
            cb(null, file.fieldname+Date.now()+path.extname(file.originalname));
          }
        }
    });
    const upload = multer({
        storage: storage,
        limits: {
            fileSize: 1024 * 1024 * 10
        },
        fileFilter: (req, file, cb) => {
            checkFileType(file, cb);
        }
    }).fields(
        [
            {
                name:'profile',
                maxCount:1
            },
            {
                name: 'natid', maxCount:1
            },
            {
                name: 'certificate', maxCount:1
            }
        ]
    );
    
    function checkFileType(file, cb) {
        if (file.fieldname === "certificate") {
            if (
                file.mimetype === 'application/pdf' ||
                file.mimetype === 'application/msword' ||
                file.mimetype === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
              ) { // check file type to be pdf, doc, or docx
                  cb(null, true);
              } else {
                  cb(null, false); // else fails
              }
        }
        else if (file.fieldname === "natid" || file.fieldname === "profile") {
            if (
                file.mimetype === 'image/png' ||
                file.mimetype === 'image/jpg' ||
                file.mimetype === 'image/jpeg'||
                fiel.mimetype==='image/gif'
              ) { // check file type to be png, jpeg, or jpg
                cb(null, true);
              } else {
                cb(null, false); // else fails
              }
            }
        }
    //at the save function 

 upload(req, res, (err) => {
        if (err) {
            console.log(err);
        } else {
            if (req.file == "undefined") {
                console.log("No image selected!")
            } else {
                let datecreated = new Date();
                let fullnames = req.body.firstname + ' ' + req.body.lastname;
                let formatedphone = '';
                let phone = req.body.personalphone;
                if (phone.charAt(0) == '0') {
                    formatedphone = '+254' + phone.substring(1);
                } else if ((phone.charAt(0) == '+') && (phone.length > 12 || phone.length <= 15)) {
                    formatedphone = phone
                }
                let teachers = {
                    "teacherid": teacherid,
                    "schoolcode": req.body.schoolcode,
                    "fullnames": fullnames,
                    "email": req.body.email,
                    "dateofbirth": req.body.dateofbirth,
                    "nationalid": req.body.nationalid,
                    "personalphone": formatedphone,
                    "profile": req.files.profile[0].path,
                    "natid": req.files.natid[0].path,
                    "certificate":req.files.certificate[0].path
                }
                connection.query('INSERT INTO teachers SET ?', teachers, (error, results, fields) => {`enter code here`
                    if (error) {
                        res.json({
                            status: false,
                            message: 'there are some error with query'
                        })
                        console.log(error);
                    } else {console.log("Saved successfully");
}

What you want is upload.fields():

app.post('/rest/upload',
         upload.fields([{
           name: 'video', maxCount: 1
         }, {
           name: 'subtitles', maxCount: 1
         }]), function(req, res, next){
  // ...
}

Tags:

Node.Js

Multer