joi_1.default.validate is not a function

hrp8sfH4xQ4 picture hrp8sfH4xQ4 · Sep 16, 2019 · Viewed 20.4k times · Source

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?

Answer

Eran Hammer picture Eran Hammer · Sep 23, 2019

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.