Amitesh Kumar
Amitesh Kumar

Reputation: 3079

Multer and express-validator creating problem in validation

I am submitting a form with an image. Using the below code.

router.post("/", upload.upload('image').single('categoryLogo'), categoryRules.categoryCreationRules(), validate, categoryController.createCategory);

It is working fine, but is some validation comes then still image is saving in disk. so what I tried is :

router.post("/", categoryRules.categoryCreationRules(), validate,upload.upload('image').single('categoryLogo'), categoryController.createCategory);

But in this express validator getting blank body so it throws validation error very time. What should I do for it, I search on google but I did not found any helpful info I am new in the node.

Rules code:

const categoryCreationRules = () => {

    return [
        check('name')
            .isLength({ min: 1 })
            .trim()
            .withMessage("Category name is required."),
        check('name').custom((name)=>{
             return CategoryModel.findOne({name: name}).collation({locale:'en',strength: 2})
                    .then(category=>{
                        if(category){
                            return Promise.reject(category.name+" category already exsist.");
                        }
                    })
        }),    
        check('name')
            .isLength({max: 100})
            .trim()
            .withMessage("Category name should not exceed more then 100 characters."),
        check('description')
            .isLength({max: 255})
            .trim()
            .withMessage("Category description should not exceed more then 255 characters.")
    ];
}

Upvotes: 7

Views: 4282

Answers (2)

Luis Paulo Pinto
Luis Paulo Pinto

Reputation: 6036

In theory, running categoryCreationRules and validate middlewares before multer would be enough. Therefore, you would only need a verification in the request body and if it contains any errors, you just return a bad request response, not letting the request pass to the next middleware (in this case the multer).

A simple example what i'm talking about: (Just to let it clear, the below code won't work)

router.post("/", categoryRules.categoryCreationRules(), validate, upload.upload('image').single('categoryLogo'), categoryController.createCategory);


const validator = (req, res, next) => {
  try {
    validationResult(req).throw();

    // Continue to next middleware, in this case, multer.
    next();
  } catch (errors) {
    // return bad request
    res.status(400).send(errors);
  }
};

this won´t work because your req.body will be undefined, as you are sending the data as a multipart/form-data (generally used to upload files). And in this case, errors will always be true.

But with multer this will not happen - you will be able to access body fields like description and name and then do the validation code.

This occurs because multer, internally, parses the multipart/form-data request to body with a library called busboy, and with this you can access fields through req.body.

Because of that, i think the best approach here is call multer middleware before your validations middlewares:

router.post("/", upload.upload('image').single('categoryLogo'), categoryRules.categoryCreationRules(), validate, categoryController.createCategory);

And after that, if the validation has an error, you delete the file created from multer and return a bad request response, something like that:

const fs = require("fs");

const validator = (req, res, next) => {
  try {
    validationResult(req).throw();

    // continue to next middleware
    next();
  } catch (errors) {
    fs.unlink(req.file.path, (err) => {
      if (err) {multipart/form-data
        /* HANLDE ERROR */
      }
      console.log(`successfully deleted ${req.file.path}`);
    });

    // return bad request
    res.status(400).send(errors);
  }
};

You can get more info about this in the below links:

node-js-with-express-bodyparser-unable-to-obtain-form-data-from-post-request

req-body-undefined-multipart

html-multipart-form-data-error-in-req-body-using-node-express

Upvotes: 4

Rupjyoti
Rupjyoti

Reputation: 399

To upload an image , you have set the enctype of form to multipart/form-data . But if you use multer later, you don't have the form data parsed, hence probaby giving undefined.

Please check multiparty , an npm module

https://www.npmjs.com/package/multiparty

It also parses other fields along with file uploads and validation might be easy to set.

Upvotes: 1

Related Questions