joi_1.default.validate не является функцией

Я хочу проверить свои экспресс-маршруты перед вызовом логики контроллера. Я использую joi и создал валидатор, который может проверять объект Request по объекту схемы.

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();
        }
    }
}

Затем я создал производный класс, который создает validationSchema и вызывает метод validateRequest. Для простоты я покажу проверку "deleteUserById".

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);
    }
}

Важное примечание: я создаю SchemaLike таким образом, потому что некоторые маршруты могут иметь params, body, query, которые необходимо проверить за один проход.

При звонке на Маршрут

УДАЛИТЬ / пользователей / 1

проверка всегда терпит неудачу. Я получаю эту ошибку

UnhandledPromiseRejectionWarning: TypeError: joi_1.default.validate не является функцией

Ошибка возникает при каждой проверке, независимо от того, правильно она вызвана или нет. Кто-нибудь знает как исправить?


person hrp8sfH4xQ4    schedule 16.09.2019    source источник


Ответы (15)


Ударьте ту же проблему при использовании express-joi-validation.

Если вы можете использовать версию 15, вы сможете перейти на более раннюю версию Joi.

npm uninstall --save @hapi/joi
npm install --save @hapi/[email protected]
person below-1    schedule 17.09.2019
comment
Извините, голосование против, потому что это больше не актуально. Версия 15 устарела. API изменен. Проверьте ответ Эрана Хаммера, он правильный. - person Sergey Yarotskiy; 26.09.2019
comment
Голосование против него. Вам не нужно использовать устаревшие API. - person fernal73; 30.05.2021

Вы исправите это, изменив joi.validate(request, validationSchema на validationSchema.validate(request, поскольку joi.validate() больше не поддерживается в версии 16. Это четко задокументировано в документации по API и примечаниях к выпуску.

person Eran Hammer    schedule 23.09.2019

Обновленная версия joi не работает с Joi.validate(req.body,schema); Не нужно использовать объект отдельно. Используйте это следующим образом. Это сработало для меня гладко. Дайте мне знать, если я в чем-то ошибаюсь:

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);
person Vaaneet Kapoor    schedule 03.11.2019

Я испытал, что joi.validate() тоже не функция. Я проверил их документацию и нашел исправление.

    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);

    
})

Это работает, как ожидалось, и больше не вызывает ошибок.

person BeardedPrince    schedule 24.06.2020

Вы можете исправить это, изменив Joi.validate(request, validationSchema) на validationSchema.validate(request), поскольку Joi.validate() больше не поддерживается в v16.

Для новой версии

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);
person Sumith Ekanayake    schedule 18.10.2020

Вместо того, чтобы понижать версию Joi, лучше быстро взглянуть на API последней версии и проверить правильный способ ее использования.

Здесь находится ссылка на последнюю на данный момент Joi API ( 16.1.7), где вы можете увидеть пример использования validate.

Также, чтобы убедиться, что вы знаете, что было изменено в следующей версии библиотеки, которую вы используете, полезно ознакомиться с примечаниями к выпуску, вот ссылка на примечания к выпуску Joi версии 16, где вы можете увидеть все изменения / новые функции, и, к вашему сведению, вы можете увидеть информацию о validate методе:

Удалите Joi.validate () и Joi.describe () (вместо этого вызовите прямой вызов схемы) (# 1941)

person komron    schedule 08.10.2019
comment
Этот ответ сработал. В схеме поместите const schemaName = Joi.object ({а затем ваши обычные данные схемы: обратите внимание, что требуется Joi.object. При его вызове просто используйте schemaName.validate (req.body) [вместо старой версии Joi.validate ( req.body, schemaName)] - person Nhon Ha; 14.10.2019

Для новой версии

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);
res.send(validation);
person kukab    schedule 04.01.2021

Вот некоторые исправления с кодами сниппетов :)

Установите ниже пакет npm.

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

файл req-validator.js

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

const registerValidation = data => {

const schema = {
    name : Joi.string().min(4).required(),
    email: Joi.string().min(4).required().email(),
    password: Joi.string().min(4).required()
};
return Joi.validate(data,schema);

}
module.exports.registerValidation = registerValidation;

наконец, вызов метода проверки в контроллере.

const router = require("express").Router();
const {registerValidation}  = require("./req-validator")

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

const {error} =  registerValidation(req.body);
if(error){
    return res.status(400).send(error.details[0].message);
}
 // logic to save in DB....
}
person Ajay Kumar    schedule 20.12.2019

Просто вы можете проверить, установлен ли у вас @ hapi / joi и требуется ли в вашем файле

и для валидации используйте этот подход.

const schema= Joi.object().keys({

    name: Joi.string().min(6).required(),
    email: Joi.string().min(6).email(),
    password: Joi.string().min(6).required()
});

 const validation = schema.validate(req.body);
    if(validation.error){
        res.status(400).send(validation.error.details[0].message);
        return ;
    }

Я думаю, это сработает

person twizeyimana elissa    schedule 03.01.2021

Создайте свою функцию проверки, как это

const validateUser = function (user) {
  const schema = Joi.object({
    username: Joi.string().min(5).max(50),
    email: Joi.string().required().email().min(5).max(255),
    password: Joi.string().required().min(5).max(1024),
  });

  return schema.validate(user);
};

Вы получите сообщение об ошибке

const { error } = validateUser({ email: 'admin' });

И сообщение об ошибке от

const message = error.details[0].message;
person the_haystacker    schedule 31.07.2020

// Получить экземпляр при определении схемы

function validate(model, object, scope) {
  const schema = getSchema(model, scope);
  return schema.validate(object);
}

// фактическая фабрика промежуточного программного обеспечения для проверки

module.exports = function ValidationMiddleware(model, scope) {
  return (req, res, next) => {
    const validationResult = validate(model, req.body, scope);
    if (validationResult.error) {
      throw new Error(validationResult.error.details[0].message);
    } else {
      next();
    }
  };
};
person irfan Quresh    schedule 16.11.2020
comment
Хотя этот код может ответить на вопрос, ответы только на код имеют ограниченную полезность для будущих посетителей этого вопроса. Рассмотрите возможность редактирования некоторых объяснений того, как и / или почему ваш код отвечает на вопрос. - person Marsroverr; 16.11.2020

использовать этот

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

insted of const schema = {...}

и подтвердите это:

const validate = schema.validate(req.body)

вместо Joi.validate (req.body, schema)

person Mudassir Ahmed    schedule 09.12.2020

Вот что-то прямо из проекта, над которым я работаю, с использованием Joi 17.3.0:

PDFCreatorController.exportAsPDF = (req, res) => {
  const data = req.body
  const schema = Joi.object().keys({
    svgDataToExport: Joi.string().required()
  })
  const isValidPromise = new Promise((resolve) => {
    const validation = schema.validate(req.body)
    if (validation.error) {
      res.status(422).json({
        status: 'error',
        message: error,
        data: data
      })
    } else {
      resolve(data)
    }
  })
  isValidPromise.then(inputDataFromUser => {
    try {
      const exportAsPDF = PDFCreatorModel.exportAsPDF(inputDataFromUser)
      exportAsPDF.then(data => {
        res.json(data)
      })
    } catch (error) {
      console.error(error)
      return res.status(500).json(error)
    }
  })
}
person Wayne Smallman    schedule 22.01.2021

Из-за Обновленной версии пакета JOI мы все сталкиваемся с этой ошибкой, но вот решение. В Node.js, когда мы сталкиваемся с этой ошибкой, мы можем решить ее, применив приведенное ниже решение.

// Example : Here we try to validate user's data
// User's POST Api 

const schema = Joi.object({
    name: Joi.string().min(1).required(),
    email:  Joi.string().required().email(),
    password: Joi.string().min(8).max(12).required(),
    isEmailVerified: Joi.boolean().required(),
    forgotPasswordToken: Joi.string().required(),
    isDeleted: Joi.boolean().required()
});
try {
    const value = await schema.validateAsync(req.body);
}
catch (err) {
    return res.status(400).send(err);
 }
person Patel Vaghesh    schedule 19.04.2021

Опустите версию дзёи. до 13.0.1 будет работать. в терминале npm я [email protected]. 2. после установки проверьте. зависимости в пакете. Json файл.

person Sanush    schedule 17.06.2021
comment
Это не дает ответа на вопрос. Как только у вас будет достаточная репутация, вы сможете комментировать любой пост; вместо этого предоставит ответы которые не требуют пояснений от автора вопроса. - Из отзыва - person Sagar Sakre; 18.06.2021