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.")
];
}
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
html-multipart-form-data-error-in-req-body-using-node-express