joi_1.default.validate is not a function

32,777

Solution 1

Hit the same problem when using express-joi-validation.

If it's ok for you to use version 15, downgrade Joi will make it.

npm uninstall --save @hapi/joi
npm install --save @hapi/[email protected]

Solution 2

You fix it by changing joi.validate(request, validationSchema to validationSchema.validate(request As joi.validate() is no longer supported in v16. It is clearly documented in the API docs and release notes.

Solution 3

Update version of joi doesn't work with Joi.validate(req.body,schema); No need to use the object separately. Use this as following. It Worked for me smoothly. Do let me know if I am wrong at anything:

const Joi = require('@hapi/joi');

const schema = Joi.object({
    name:Joi.string().min(3).required(),
    email:Joi.string().min(4).required().email(),
    password:Joi.string().min(6).required()
});





router.post('/register', async (req,res) => {


    //updated joi
    
   // This is a shorter version
    const { error } = schema.validate(req.body);

    // Error in response

    res.send(error.details[0].message);


    // WORKING WITH DEPRECATED VERSION
    // const Validation = Joi.validate(req.body,schema);
    // res.send(Validation);

Solution 4

I experienced joi.validate() is not a function also. I checked their documentation and got a fix for it.

    const Joi = require('@hapi/joi');

const schema = Joi.object({
    name:Joi.string().min(6).required(),
    email:Joi.string().min(6).required().email(),
    password:Joi.string().min(6).required()
});

router.post('/register',  (req, res) => {

    // VALIDATE BEFORE SAVING A USER 
    const Validation = schema.validate(req.body);
    res.send(Validation);

    
})

This works as expected and gives no further error.

Solution 5

You can fix it by changing Joi.validate(request, validationSchema) to validationSchema.validate(request) As Joi.validate() is no longer supported in v16.

For new version

const schema = Joi.object({ name: Joi.string() .min(6) .required(),
email: Joi.string() .min(6) .required() .email(),
password: Joi.string() .min(6) .required() });

const validation = schema.validate(req.body);
Share:
32,777
hrp8sfH4xQ4
Author by

hrp8sfH4xQ4

Updated on October 28, 2021

Comments

  • hrp8sfH4xQ4
    hrp8sfH4xQ4 over 2 years

    I want to validate my Express routes before calling the controller logic. I use joi and created a validator which is able to validate the Request object against the schema object

    import { Request, Response, NextFunction } from 'express';
    import joi, { SchemaLike, ValidationError, ValidationResult } from '@hapi/joi';
    import { injectable } from 'inversify';
    
    @injectable()
    export abstract class RequestValidator {
        protected validateRequest = (validationSchema: SchemaLike, request: Request, response: Response, next: NextFunction): void => {
            const validationResult: ValidationResult<Request> = joi.validate(request, validationSchema, {
                abortEarly: false
            });
    
            const { error }: { error: ValidationError } = validationResult;
    
            if (error) {
                response.status(400).json({
                    message: 'The request validation failed.',
                    details: error.details
                });
            } else {
                next();
            }
        }
    }
    

    Next I created a deriving class which creates the validationSchema and calls the validateRequest method. For the sake of simplicity I will show the "deleteUserById" validation

    import { Request, Response, NextFunction } from 'express';
    import joi, { SchemaLike } from '@hapi/joi';
    import { injectable } from 'inversify';
    
    import { RequestValidator } from './RequestValidator';
    
    @injectable()
    export class UserRequestValidator extends RequestValidator {
        public deleteUserByIdValidation = async (request: Request, response: Response, next: NextFunction): Promise<void> => {
            const validationSchema: SchemaLike = joi.object().keys({
                params: joi.object().keys({
                    id: joi.number().required(),
                })
            });
    
            this.validateRequest(validationSchema, request, response, next);
        }
    }
    

    Important note: I create the SchemaLike that way because some routes might have params, body, query which need to get validated in one run.

    When calling the Route

    DELETE /users/1

    the validation always fails. I get this error

    UnhandledPromiseRejectionWarning: TypeError: joi_1.default.validate is not a function

    The error occurs with every validation, whether called correctly or not. Does someone know how to fix it?