node.jsmulter

Get req.body of other fields than files before multer uploads the files


I have a function that uses multer that uploads files:

exports.create = (req, res) => {
    console.log("req.body1 : ")
    console.log(req.body)
    var fileFilter = function (req, file, cb) {
        console.log("req.body2: ")
        console.log(req.body)
        // supported image file mimetypes
        var allowedMimes = ['image/jpeg', 'image/pjpeg', 'image/png', 'image/gif'];

        if (_.includes(allowedMimes, file.mimetype)) {
            // allow supported image files
            cb(null, true);
        } else {
            // throw error for invalid files
            cb(new Error('Invalid file type. Only jpg, png and gif image files are allowed.'));
        }
    };

    let upload = multer({
        storage: multer.diskStorage({
            destination: (req, file, callback) => {
                console.log("req.body3 : ")
                console.log(req.body)
                let userId = req.params.userId;
                let pathToSave = `./public/uploads/${userId}/store`;
                fs.mkdirsSync(pathToSave);
                callback(null, pathToSave);
            },
            filename: (req, file, callback) => {
                callback(null, uuidv1() + path.extname(file.originalname));
            }
        }),
        limits: {
            files: 5, // allow only 1 file per request
            fileSize: 5 * 1024 * 1024, // 5 MB (max file size)
        },
        fileFilter: fileFilter
    }).array('photo');

    upload(req, res, function (err) {
        console.log("req.body4 : ")
        console.log(req.body)
...
...

As you see there are lots of console.log that prints out info of incoming data by POST method. Strange thing is that fields other than files does not appear until it enters to last upload function.

So the problem is I can't validate things using those fields until it reaches to last upload function. So I cannot cancel and delete the uploded files if there exists any errors in other fields than files.

Following is outputs of above code:

req.body : 
{}
req.body2: 
{}
req.body3 : 
{}
req.body4 : 
{ name: '1111111111',
  price: '1212',
  cid: '1',
...

File uploads are done around console.log("req.body3 : "). Then it outputs other fields in console.log("req.body4 : "). I need those other fields that appears in req.body4 to validate stuffs before actually uploading the files. But I can't because those fields are retrieved after the file is uploaded.

How can I get fields of others before multer actually uploads the file?

===============================================

APPENDED:

I found that if I use .any() instead of .array('photo') then I can access both fields and files. But still, the problem is that it uploads those files first then gives me the access to the those field in uploads function at the bottom where console.log("req.body4 : ") is. so still the problem is that files get uploaded first before I need to validate using those fields.


Solution

  • you should be receiving an object in your body only one object so you should be able to access it like any other object

    {
      object1: 'something here',
      object2: {
        nestedObj1: {
          something: 123,
          arrInObj: ['hello', 123, 'cool'],
      }
    }
    

    then you would be able to access these things like so:

    console.log(req.body.object1) // 'something here'
    console.log(req.body.object2.nestedObj1[0]) // 'hello'
    console.log(req.body.object2.nestedObj1.forEach(item => console.log(item)) // 'hello' 123 'cool'