Home > other >  Joi validation for a decimal number not working properly
Joi validation for a decimal number not working properly

Time:11-02

I am validating the request body for one of the API I am working on to insert the data in the DB. DB has precision as 3.

Below is the schema -

const insertDetails = {
  body: Joi.object({
    id: Joi.string().length(6).required(),
    startdate: Joi.date().format('YYYY-MM-DD').required(),
    enddate: Joi.date().format('YYYY-MM-DD').required(),
    role: Joi.number().valid(5).required(),
    fnum: Joi.number().less(1.500).precision(3).required(),
    user: Joi.string().max(8).required()
  })
}

My understanding is for fnum that it'll only allow decimal precision upto 3 and should throw an error if there's a number like 1.345678 saying the precision should be 3.

But it goes through and while inserting the data , it rounds to 3 decimal places in the database.

I tried searching online and see that we can validate or set the convert to false but I am having difficulty doing it for just one of the field here i.e. fnum.

Joi.validate(insertDetails, {"convert": false})

I added above line but it throws an error saying

TypeError: Joi.validate is not a function

Any suggestions as to how can I validate the precision of the fnum in the request and should throw an error if the precision is more?

CodePudding user response:

Define schema like this-

const insertSchema = Joi.object({
    id: Joi.string().length(6).required(),
    startdate: Joi.date().format('YYYY-MM-DD').required(),
    enddate: Joi.date().format('YYYY-MM-DD').required(),
    role: Joi.number().valid(5).required(),
    fnum: Joi.number().less(1.500).precision(3).required(),
    user: Joi.string().max(8).required()
  })

Then Use the validate function with the schema-

const {error, value} = insertSchema.validate(req.body,{"convert": false});

You can place the req.body object as the first params and the next params will be options.

And this function will return an object with error and value.


Or you can create a middleware like this for routes-

const validateRequest = (
  req,
  next,
  schema,
  options = {
    abortEarly: false, // include all errors
    allowUnknown: true, // ignore unknown props
    stripUnknown: true, // remove unknown props
  },
) => {
  const { error, value } = schema.validate(req.body, options);
  if (error) {
    const error_ = new Error(`Validation error: ${error.details.map((x) => x.message).join(', ')}`);
    error_.statusCode = 400;
    throw error_;
  } else {
    req.body = value;
    next();
  }
};

Then create your schema with validateRequest function-


const insertSchema = (req, res, next) => {
  const schema = Joi.object({
      id: Joi.string().length(6).required(),
      startdate: Joi.date().format('YYYY-MM-DD').required(),
      enddate: Joi.date().format('YYYY-MM-DD').required(),
      role: Joi.number().valid(5).required(),
      fnum: Joi.number().less(1.5).precision(3).required(),
      user: Joi.string().max(8).required(),
    });
  validateRequest(req, next, schema);
};

Then use it in your router as a middleware-

router.post('/create-post', insertSchema, (req, res, next) => {
   // Do rest of the code
});
  • Related