0

I am new to express-validator and multer. In My project, I create a form for users to enter him/her details. my validation not work when i use multer.

multer attached body object to the requerst object like this

 form Data: >>>[Object: null prototype] {
          'person-fullname': 'Amit vadgama',
          'person-email': '',
          'person-gender': '',
          'person-mobile': '',
          'person-dob': '',
          'person-address-ln1': '',
          'person-address-ln2': '',
          'person-country': '',
          'person-state': '',
          'person-city': '',
          'person-zipcode': '',
          currentStep: 'step1'
        }

and this will fail my validation, How to get rid of this problem :(

My Form

<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
  <h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Personal Details</h4>

  <div class="flex w-full">
    <div class="flex flex-col w-1/2 mr-10">
      <label for="person-fullname">Full Name</label>
      <input 
        type="text" 
        class="form-input border <%if(errorObj['person-fullname']){%>border-red-700<%}%>" 
        name="person-fullname" 
        id="person-fullname" 
        value="<%if(oldValue['person-fullname']){%><%=oldValue['person-fullname']%><%}%>">
      
      <%if(errorObj["person-fullname"]){%>
        <span class="text-red-700"><%= errorObj["person-fullname"] %></span>
      <%}%>
    </div>

    <div class="flex flex-col w-1/2">
      <label for="person-email">Email</label>
      <input 
        type="email"
        class="form-input border <%if(errorObj['person-email']){%>border-red-700<%}%>" 
        name="person-email" 
        id="person-email" 
        value="<%if(oldValue["person-email"]){%><%=oldValue["person-email"]%><%}%>">

        <%if(errorObj["person-email"]){%>
          <span class="text-red-700"><%= errorObj["person-email"] %></span>
        <%}%>
    </div>
  </div>

  <div class="flex w-full mt-5">
    <div class="flex flex-col w-1/2 mr-10">
      <label for="person-gender">Gender</label>
      <select class="border py-[9px] <%if(errorObj['person-gender']){%>border-red-700<%}%>" name="person-gender" id="person-gender">
        <option value="">Select Gender</option>
        <% Object.entries({'m':'male','f':'female','o':'other'}).forEach(([key,val]) => {%>
            <% if(oldValue["person-gender"] == key) {%>
              <option value="<%=key%>" selected><%=val%></option>
            <%}else{%>
              <option value="<%=key%>"><%=val%></option>
         <% }}) %>
        </select>
      <%if(errorObj["person-gender"]){%>
        <span class="text-red-700"><%= errorObj["person-gender"] %></span>
      <%}%>
    </div>
    <div class="flex flex-col w-1/2">
      <label for="person-mobile">Mobile no.</label>
      <input 
        type="tel" 
        class="form-input border <%if(errorObj['person-mobile']){%>border-red-700<%}%>" 
        name="person-mobile" 
        id="person-mobile" 
        value="<%if(oldValue['person-mobile']){%><%=oldValue['person-mobile']%><%}%>">
        
        <%if(errorObj["person-mobile"]){%>
          <span class="text-red-700"><%= errorObj["person-mobile"] %></span>
        <%}%>
    </div>
    
  </div>

  <div class="flex w-full mt-5">
    <div class="flex flex-col w-1/2 mr-10">
      <label>Birth Date</label>
      <input
       type="date" 
       class="border py-[9px] <%if(errorObj['person-dob']){%>border-red-700<%}%>" 
       name="person-dob" 
       value="<%if(oldValue['person-dob']){%><%=oldValue['person-dob']%><%}%>">

       <%if(errorObj["person-dob"]){%>
        <span class="text-red-700"><%= errorObj["person-dob"] %></span>
      <%}%>
    </div>
    <div class="flex flex-col w-1/2">
      <label>Profile Image</label>
      <input type="file" class="form-input border <%if(errorObj['person-image']){%>border-red-700<%}%>" name="person-image" value="">
      <%if(errorObj["person-image"]){%>
        <span class="text-red-700"><%= errorObj["person-image"] %></span>
      <%}%>
    </div>
  </div>

  <div class="block mt-5 border p-3">
    <h5 class="mb-4 text-md font-semibold text-gray-600 dark:text-gray-300">Document</h5>
    <div class="flex items-center <%if(errorObj['person-doc-type']){%>border border-red-700<%}%>">
      <label for="person-doc-dl" class="mr-5">
        <input type="radio" name="person-doc-type" id="person-doc-dl" <%if(oldValue['person-doc-type'] == 'dl'){%>checked<%}%> value="dl">
        <span>Driving Licence</span>
      </label>
      <label for="person-doc-vi" class="mr-5">
        <input type="radio" name="person-doc-type" id="person-doc-vi" <%if(oldValue['person-doc-type'] == 'vi'){%>checked<%}%> value="vi">
        <span>Voter Id</span>
      </label>
      <label for="person-doc-aadhar" class="mr-5">
        <input type="radio" name="person-doc-type" id="person-doc-aadhar" <%if(oldValue['person-doc-type'] == 'aadhar'){%>checked<%}%> value="aadhar">
        <span>Aathar</span>
      </label>
      <label for="person-doc-pan" class="mr-5">
        <input type="radio" name="person-doc-type" id="person-doc-pan" <%if(oldValue['person-doc-type'] == 'pan'){%>checked<%}%> value="pan">
        <span>PAN</span>
      </label>
      <label for="person-doc-pass" class="mr-5">
        <input type="radio" name="person-doc-type" id="person-doc-pass" <%if(oldValue['person-doc-type'] == 'pass'){%>checked<%}%> value="pass">
        <span>Passport</span>
      </label>
      <label for="person-doc-rc" class="mr-5">
        <input type="radio" name="person-doc-type" id="person-doc-rc" <%if(oldValue['person-doc-type'] == 'rc'){%>checked<%}%> value="rc">
        <span>Rasan Card</span>
      </label>
      <%if(errorObj["person-doc-type"]){%>
        <span class="text-red-700"><%= errorObj["person-doc-type"] %></span>
      <%}%>
    </div>

    <div class="flex w-full mt-5">
      <div class="flex flex-col w-1/2 mr-10">
        <label for="person-doc-front">Uploade Document(Front)</label>
        <input type="file" class="form-input border <%if(errorObj['person-doc-front']){%>border-red-700<%}%>" name="person-doc-front" value="">
        <%if(errorObj["person-doc-front"]){%>
          <span class="text-red-700"><%= errorObj["person-doc-front"] %></span>
        <%}%>
      </div>
      <div class="flex flex-col w-1/2 <%if(oldValue['person-doc-type'] != 'aadhar'){%>hidden<%}%>">
        <label for="person-doc-back">Uploade Document(Back)</label>
        <input type="file" class="form-input border <%if(errorObj['person-doc-back']){%>border-red-700<%}%>" name="person-doc-back" value="">
        <%if(errorObj["person-doc-back"]){%>
          <span class="text-red-700"><%= errorObj["person-doc-back"] %></span>
        <%}%>
      </div>
    </div>
  </div>

  <div class="flex w-full mt-5">
    <div class="flex flex-col w-1/2 mr-10">
      <label for="person-address-ln1">Address Line-1</label>
      <input 
        type="text" 
        class="form-input border <%if(errorObj['person-address-ln1']){%>border-red-700<%}%>" 
        name="person-address-ln1" id="person-address-ln1" value="<%if(oldValue['person-address-ln1']){%><%=oldValue['person-address-ln1']%><%}%>">
      <%if(errorObj["person-address-ln1"]){%>
        <span class="text-red-700"><%= errorObj["person-address-ln1"] %></span>
      <%}%>
    </div>
    <div class="flex flex-col w-1/2">
      <label for="person-address-ln2">Address Line-2</label>
      <input type="text" class="form-input border" name="person-address-ln2" id="person-address-ln2" value="">
    </div>
  </div>

  <div class="flex w-full mt-5">
    <div class="flex flex-col w-1/2 mr-10">
      <label for="person-country">Country</label>
      <select class="form-input border <%if(errorObj['person-country']){%>border-red-700<%}%>" name="person-country" id="person-country">
        <option value="">Choose Country</option>
        <%if(country){%>
          <% Object.entries(country).forEach(([key,val])=>{ %>

            <% if(oldValue['person-country'] == key) {%>
              <option value="<%= key %>" selected><%= val %></option>
            <%}else{%>
              <option value="<%= key %>"><%= val %></option>
          <% }}) %>
        <%}%>
      </select>

      <%if(errorObj["person-country"]){%>
        <span class="text-red-700"><%= errorObj["person-country"] %></span>
      <%}%>
    </div>
    <div class="flex flex-col w-1/2">
      <label for="person-state">State</label>
      <select class="form-input border" name="person-state" id="person-state">
          <option value="">select state</option>
      </select>
    </div>
  </div>

  <div class="flex w-full mt-5">
    <div class="flex flex-col w-1/2 mr-10">
      <label for="person-city">City</label>
      <input 
        type="text" 
        class="form-input border <%if(errorObj['person-city']){%>border-red-700<%}%>" 
        name="person-city" 
        id="person-city" 
        value="<%if(oldValue['person-city']){%><%=oldValue['person-city']%><%}%>">

        <%if(errorObj["person-city"]){%>
          <span class="text-red-700"><%= errorObj["person-city"] %></span>
        <%}%>
    </div>
    <div class="flex flex-col w-1/2">
      <label for="zipcode">Zip code</label>
      <input 
        type="text" 
        class="form-input border <%if(errorObj['person-zipcode']){%>border-red-700<%}%>" 
        name="person-zipcode" 
        id="person-zipcode" 
        value="<%if(oldValue['person-zipcode']){%><%=oldValue['person-zipcode']%><%}%>">

        <%if(errorObj["person-zipcode"]){%>
          <span class="text-red-700"><%= errorObj["person-zipcode"] %></span>
        <%}%>
    </div>
  </div>
  <div class="w-full text-end">
    <button next-step-btn class="
        bg-purple-700
        px-4
        py-3
        mt-10
        text-white
      ">
      Next
    </button>
  </div>
</div>

My validation cod

const { body } = require("express-validator");

const newPersonValidator = () => {
  return [
    body("person-fullname")
      .isLength({ min: 2 })
      .withMessage("Name is too small")
      .isLength({ max: 50 })
      .withMessage("Name is too big")
      .matches("^[a-zA-Z ]+$")
      .withMessage("Please enter valid Name"),

    /* ----------------------------------------------------------------------------------- */
    body("person-email").isEmail().withMessage("Please enter valid email"),
    /* ----------------------------------------------------------------------------------- */
    body("person-gender").custom((value, { req }) => {
      if (value.trim() == "") {
        throw new Error("Please select gender")
      }
      return true;
    }),
    /* ----------------------------------------------------------------------------------- */
    body("person-mobile", "Please enter valid mobile no")
      .isLength({ min: 1 })
      .isMobilePhone(),
    /* ----------------------------------------------------------------------------------- */
    body("person-dob").custom((value,{req})=>{
      if(value == ''){
        throw new Error("Date of birth is required")
      }

      const oldDt = new Date(value);
      const current = new Date();

      const diff = current.getFullYear() - oldDt.getFullYear();

      if(diff < 10){
        throw new Error("Person should be at least 10 years old")  
      }
      
      return true;
    }),
    /* ----------------------------------------------------------------------------------- */
    body("person-doc-type").custom((value)=>{
      if(value == undefined){
        throw new Error("please select document type");
      }
      return true
    }),
    /* ----------------------------------------------------------------------------------- */
    body("person-address-ln1")
    .isLength({min:1}).withMessage("Please enter address")
    .matches("^[a-zA-Z0-9  -:]+$").withMessage("Please enter valid address"),
    /* ----------------------------------------------------------------------------------- */
    body("person-country").custom((value, { req }) => {
      console.log(req.body);
      console.log(req.file);
      if (value.trim() == "") {
        throw new Error("Please select country")
      }
      return true;
    }),
    /* ----------------------------------------------------------------------------------- */
    body("person-city","Please enter valid city name").isLength({min:3, max:20}).isAlpha(),
    /* ----------------------------------------------------------------------------------- */
    body("person-zipcode","Please enter valid zipcode").isLength({min:1, max:6}).isAlphanumeric()

  ]
}

module.exports = newPersonValidator;

my controller function

const postNewPgPersonFrm = (req, res, next) => {
    
    const uploadFields = [
        { name: 'person-image', maxCount: 1 },
        { name: 'person-doc-front', maxCount: 1 },
        { name: 'person-doc-back', maxCount: 1 }
    ]
    fileUploads.fields(uploadFields)(req, res, (err) => {

        const parseError = {};
        
        if (err) {
            throw new Error(err);
            // parseError[err.field] = err.errorDetail;
        }

        /**
         * Check if user not upload profile image and document then give error
         */
        if(req.file == undefined){
            parseError['person-image'] = "Please upload profile image";
            parseError['person-doc-front'] = "Please upload id doc";

            if(req.body["person-doc-type"] == 'aadhar'){
                parseError['person-doc-back'] = "Please upload id doc";
            }
            
        }

        const ses = req.session;
        let currentStep = req.body.currentStep;

        /**
         * Fetch error from requrest object
         */
        const errors = validationResult(req);
        console.log("form Data: >>> ",req.body);
        /**
         * If it has error then send error object and old data to the view
         */
        if (!errors.isEmpty()) {
            const allError = errors.array();
            allError.forEach(err => {
                parseError[err.path] = err.msg
            });
            
            console.log(parseError);

            return renderView(req, res, "pages/dashboard/pg-person/create-person", {
                pageTitle: "Add New Person",
                steps: {
                    step1: req.session.step1,
                    step2: req.session.step2,
                    step3: req.session.step3,
                    step4: req.session.step4,
                },
                currentStep: currentStep,
                country: getAllCountry,
                errorObj: parseError,
                oldValue: req.body
            });
        }
        console.log("uploade Errors:",parseError);

        /**
         * If no error then we reach here and we good to go 
         */

        if (currentStep == "step1" && !ses.step1.isCompleted) {
            ses.step1.isCompleted = true;
            currentStep = "step2";
        } else if (currentStep == "step2" && !ses.step2.isCompleted) {
            ses.step2.isCompleted = true;
            currentStep = "step3";
        } else if (currentStep == "step3" && !ses.step3.isCompleted) {
            ses.step3.isCompleted = true;
            currentStep = "step4";
        } else if (currentStep == "step4" && !ses.step4.isCompleted) {
            ses.step4.isCompleted = true;
            currentStep = "success";
        } else {

        }

        renderView(req, res, "pages/dashboard/pg-person/create-person", {
            pageTitle: "Add New Person",
            steps: {
                step1: req.session.step1,
                step2: req.session.step2,
                step3: req.session.step3,
                step4: req.session.step4,
            },
            currentStep: currentStep,
            country: getAllCountry
        });

    });
}

enter image description here

Thanks

  • what error do you get? for which field? – yeya Jul 16 '23 at 08:30
  • I not getting any error but, If I will fill the form with all required data then it still shows the validation error messages. – Amit Vadgama Jul 16 '23 at 10:12
  • How is the body looks at console when you print it at `form Data: >>> `? – yeya Jul 16 '23 at 10:38
  • It's look like as I attached in my ticket above – Amit Vadgama Jul 16 '23 at 11:29
  • Maybe that can help you: https://stackoverflow.com/a/64666132/3107689. Anyway, try to narrow your surface, try to post a form and validate only with a single field. It will be much easier to debug and much easier to help you in case you won't solve it – yeya Jul 17 '23 at 15:00
  • @yeya Thanks For your efforts, yesterday I figured it out and solved the issue by moving my file upload code to the router as middelware `const uploadFields = [ { name: 'person-image', maxCount: 1 }, { name: 'person-doc-front', maxCount: 1 }, { name: 'person-doc-back', maxCount: 1 }] router.post("/person/create-new",fileUploads.fields(uploadFields),newPersonValidator(), postNewPgPersonFrm);` – Amit Vadgama Jul 17 '23 at 16:41

0 Answers0