Manimaran
Manimaran

Reputation: 405

How to validate multipart/form-data in Express-validator using Nodejs

A snippet of my code where i show my defined router,checking body param and checking for validation error.

My defined Post request:

router.post("/addEmployee",upload.any(), function(req, res, next) {

  /*I used multer because body data from multipart/form-data*/

var input = JSON.parse(req.body.data);

Server validation: // validation not work because req.checkBody only get bodyData now i am using multipart/form-data (req.body.data)

req.checkBody('EMPID', "**EMPID must be Integer**").notEmpty().isNumeric();

req.checkBody('PAYROLLID', "**PAYROLLID must be Integer**").notEmpty().isNumeric();


.....

....

Check validation error

var validationError = req.validationErrors(); //check error


// if (validationError) { //suppose get error -- throw that error


 res.json(validationError[0].msg);


 } else { //validation success


......strong text

Upvotes: 9

Views: 22302

Answers (4)

olawalejuwonm
olawalejuwonm

Reputation: 1527

This works for me on the route part of desired endpoint

var express = require("express");
var router = express.Router();
const grant = require("../controllers/grant");
const { body, check } = require("express-validator");
const {
  authenticate,
  checkIfAdmin,
  checkIfSuper,
  checkIfApplicant,
} = require("../middlewares/authentication");
const { validateGrant } = require("../middlewares/validator");
const { uploadHandler } = require("../middlewares/call");

const {
  multerUpload,
  cloudinaryConfig,
  paystack,
} = require("../config/config");
 uploadHandler = (req, res, next) => {
  req.upload(req, res, (err) => {
      if (err) {
          res.status(400)
              .json({ message: `Bad request upload handler, ${err.message}`, success: false })
              .end();
      } else {
          // special workaround for files validating with express-validator
          req.body.files = req.files; 
          next();
          // console.log("req.files", req.upload, "here", req.files, "body",   req.body.files);

      }
  });
};

router.post(
  "/create",
  authenticate,
  checkIfSuper,
  function (req, res, next) {
    req.upload = multerUpload.fields([
      { name: "main", maxCount: 1 },
      { name: "banner", maxCount: 1 },
    ]);
    next();
  },
  uploadHandler,
  [
    check("name").not().isEmpty().withMessage("Grant Name is required"),
    check("description")
      .isString()
      .withMessage("Grant Description is required"),
    check("sdgGoals")
      .not()
      .isEmpty()
      .withMessage("Grant Sdg Goals are required"),
    check("deadline")
      .not()
      .isEmpty()
      .withMessage("Grant Application Deadline is required"),
    check("available")
      .isBoolean()
      .withMessage("Grant Availability is required"),
    check("about").isString().withMessage("Grant About is required"),
    check("by").isString().withMessage("Grant Creator is required"),
  ],
  cloudinaryConfig,
  grant.create
);

grant.create is

const { error } = require("../middlewares/response");
const { grants } = require("../models/grant");
const { validationResult } = require("express-validator");
const Datauri = require("datauri/parser");
const path = require("path");
const { uploader } = require("../config/config");

exports.create = async function (req, res, next) {
  try {
    const errors = validationResult(req);

    if (!errors.isEmpty()) {
      return res.status(400).json({
        success: false,
        message: errors.array()[0].msg,
      });
    }

    if (!req.files) { 
      return res.status(400).json({
        success: false,
        message: "No files were uploaded",
      });
    }
    const dUri = new Datauri();
    const dataUri = (file) =>
      dUri.format(path.extname(file.originalname).toString(), file.buffer);
    const {
      title,
      description,
      sdgGoals,
      applicationDeadline,
      applicationLimit,
      available,
    } = req.body;
    let promises = [];
    let imgs = [];
    // console.log("req.files", req.files, "here", req.body.files);

    for (const key in req.files) {
      if (Object.hasOwnProperty.call(req.files, key)) {
        const f = req.files[key][0];
          console.log(f, "before uri")
          //console.log(dataUri(f)); -> //fileName: '.png', mimetype: 'image/png', and content
          const file = dataUri(f).content;
    
          try {
            const resp = await uploader.upload(file);
            // console.log("resp url and image", resp.url, image);
            imgs.push({ name: key, url: resp.url });
            
          } catch (err) {
            return next(err);
          }
        
        
      }
    }
    console.log("imgs", imgs);


    const grant = new Grant({
      ...req.body,
      createdBy: req.user._id,
      images: imgs,
    });
    const result = await grant.save();
    return res.status(201).json({
      message: "Grant created successfully",
      data: {
        grant: result,
      },
    });
  } catch (err) {
    next(err);
  }
};

Upvotes: 0

Abdul Manan
Abdul Manan

Reputation: 2375

exports.create = function (req, res) {
    req.assert('name', 'Name cannot be blank').notEmpty();
    req.assert('email', 'Email is not valid').isEmail();
    req.assert('password', 'Password cannot be blank').notEmpty();
    req.assert('password', 'Password must be at least 8 chars long').isLength({ min: 8 });

    const errors = req.validationErrors();

    if (errors) {
        return res.status(200).send(errors);
    }
    req.body.password = bcrypt.hashSync(req.body.password, 10);
    var model = new Admin(req.body);
    model.save(function (err, admin) {
        if (err) {
            res.status(500).send({ error: err });
            return;
        } else {
            res.status(200).send(admin);
        }
    });
};

Upvotes: -1

Kumar Subedi
Kumar Subedi

Reputation: 354

Use express validator middleware after the multer that's why express validator work naturally

This example work for me , try this

import require dependencies

var fs = require('fs');
var path = require('path');
var multer = require('multer');
var mkdirp = require('mkdirp');

configure multer

var obj = {};
var diskStorage = multer.diskStorage({

    destination:function(req,file,cb){

        var dest = path.join(__dirname,'/uploads');

        mkdirp(dest,function(err){
            if(err) cb(err,dest);
            else cb(null,dest);
        });
    },
    filename:function(req,file,cb){
        var ext = path.extname(file.originalname);
        var file_name = Date.now()+ext;
        obj.file_name = file_name;
        cb(null,file_name);
    }
});
var upload = multer({storage:diskStorage});

prepare validation middleware

 var validator = function(req,res,next){

            req.checkBody('name').notEmpty().withMessage('Name field is required');
            req.checkBody('email')
            .notEmpty()
            .withMessage('Email field is required')
            .isEmail()
            .withMessage('Enter a valid email address')
            .isEmailExists()
            .withMessage('Email address already exists');

            req.checkBody('password').notEmpty().withMessage('Password field is required');
            req.checkBody('retype_password').notEmpty().withMessage('Retyp password field is required');

            req.checkBody('password').isEqual(req.body.retype_password).withMessage('Password and confirm password did not match.');

            req.checkBody('address').notEmpty().withMessage('Address field is required');

            req.asyncValidationErrors().then(function() {
                next();
            }).catch(function(errors) {
                req.flash('errors',errors);
                res.status(500).redirect('back');
            });

        }

save requested data into db

router.post('/store',upload.single('avatar'),validator,async function(req,res,next){

            var newUser = User({
                name:req.body.name,
                email:req.body.email,
                password:req.body.password,
                avatar:obj.file_name,
                address:req.body.address,
                created_at:new Date()
            });

            try{
                await newUser.save();
                req.flash('success_message','New user has been successfully created');
                return res.redirect('back');

            }catch(err){
                throw new Error(err);
            }
    });

Upvotes: 12

Manimaran
Manimaran

Reputation: 405

Guys I find one solution

router.post("/addEmployee",upload.any(), function(req, res, next) {

   /*I used multer because body data from multipart/form-data*/

   var input = JSON.parse(req.body.data);

   req.body = input;// solution this line
});

Upvotes: 2

Related Questions