Search code examples
node.jsexpressmulter

multer how to access multipart form data before uploading files


I am trying to handle form which submits text fields and upload files, I am using multer to handle file uploads and express-validator to validate other fields.

With multipart form, I can not access req.body before parsing it with multer, which means I have to register multer middleware before other middlewares that need that req.body. I want to know if I can upload the files, only if other fields in the form are valid, is there a way to access req.body without parsing with multer ?

multer setup

const multer = require('multer');

const storage = multer.diskStorage({
  destination: path.join(__dirname, `../public/images/games/temp/`),
  filename: (req, file, cb) => {
    if(file.fieldname === "cover") {
      cb(null, `main.jpg`);  
    } else if(file.fieldname === "screenshots") {
        if(!req.count)
          req.count = 1;

        cb(null, `ss-${req.count++}.jpg`);
    }
  }
});

const upload = multer({storage});

route handler

exports.game_create_post = [
  upload.fields([{name: "cover", maxCount: 1}, {name: "screenshots", maxCount: 10}]),

  body("a field").validator(),
  body("a field").validator(),
  body("a field").validator(),

  // other middlewares...
]

Solution

  • You can access the other fields through the your filter like so :

    var upload = multer({
        storage: storage,
        fileFilter : (req, file, cb) => { uploadFilter(req, file, cb) },
    });
    
    function addComicFilter(req, file, cb) {
        //Here you can access the other fields
        console.log(req.body.title)
        console.log(req.body.description)
        //and you won't get undefined anymore.
        //so do your validation here.
    }
    
    app.post('/addComic', upload.single('image'), function (req, res, next) {
    
     //Can't access other fields through req.body.<Name of the field>
     //You can only access those through the uploadFilter function so your validation
     //should be there.
    }