簡體   English   中英

Joi 驗證錯誤來自哪個字段在 UI 中顯示錯誤

[英]Joi validation error from which field to show error next to it in UI

我必須使用 Joi 驗證庫來驗證 API 輸入,然后發送輸出。

我說過創建了一個模式如下:

import Joi from '@hapi/joi'

const eventSchema = Joi.object({
  title: Joi.string()
    .min(7)
    .max(50)
    .required()
    .error(() => Error('Event title has to be least 7 and max 50 characters.')),

  description: Joi.string()
    .min(10)
    .max(400)
    .required()
    .error(() => Error('Event description has to be least 10 and max 400 characters.')),

  place: Joi.string()
    .min(6)
    .max(40)
    .required()
    .error(() => Error('Event place has to be least 6 and max 40 characters.'))
})
export default eventSchema

當我驗證這一點時,我得到了預期的驗證錯誤。 這里的問題是我不知道哪個字段真正導致了錯誤。 我想知道這一點,因為我想確切地顯示導致錯誤的字段旁邊的錯誤,而不僅僅是顯示在表單頂部的通用驗證消息。

const isValid = eventSchema.validate()

if (isValid.error) {
  const fieldNameWhichCauseError = ???

  return {
   errors: { [fieldNameWhichCauseError]: isValid.error.message }
  }
}

// Everything looks good save to db
// ...etc.

上面的代碼現在可以知道fieldNameWhichCauseError = ??? 中的字段名稱 . 有人能幫幫我嗎? 我還沒有看到有人做這樣的場景。 我也沒有在文檔中找到。 我有很多模式和驗證,這真的阻止了我在 UI 中的適當位置顯示錯誤。

我自己想通了。 有一天它可能會幫助某人在這里搜索。

首先,我將創建一個自定義 ValidationError 對象。

class ValidationError extends Error {
   constructor(message, fieldName) {
     super(message)
     this.fieldName = fieldName
   }
}

現在在上面發布在問題中的代碼中使用這個類。 使用 ValidationError 而不是 Error 類,並將字段名稱傳遞給它。 例子

const eventSchema = Joi.object({
  title: Joi.string()
    .min(7)
    .max(50)
    .required()
    .error(() => new ValidationError('Event title has to be least 7 and max 50 characters.', 'title'))
})

記住在使用自定義類時使用new 驗證的代碼可以從傳遞下來的錯誤對象中獲取error.fieldName值。

我希望這是正確的方法。 如果有更好的方法,請張貼我會接受它作為答案。

我認為有更好的方法來實現這一點,因為不推薦使用拋出錯誤來實現這一點。 ( https://github.com/hapijs/joi/blob/master/API.md#anyerrorerr )

您應該利用any.messages ( https://github.com/hapijs/joi/blob/master/API.md#anymessagesmessages ) 並添加您的自定義消息。 根據您定義它們的方式,即使用戶沒有指定任何內容,您也總是會收到相同類型的錯誤消息。 還使用錯誤覆蓋abortEarly選項。 這意味着您不會收到所有消息,只會收到第一條消息。

可以像這樣使用消息。

const Joi = require('@hapi/joi');
const eventSchema = Joi.object({
    title: Joi.string()
        .min(7)
        .max(50)
        .required()
        .messages({
            'string.base': `"description" should be a type of 'text'`,
            'string.min': '"title" has to be least {#limit} characters.',
            'string.max': '"title" has to be max {#limit} characters.',
            'any.required': `"title" is a required field`,
        }),

    description: Joi.string()
        .min(10)
        .max(400)
        .required()
        .messages({
            'string.base': `"description" should be a type of 'text'`,
            'string.min': '"description" has to be least {#limit} characters.',
            'string.max': '"description" has to be max {#limit} characters.',
            'any.required': `"description" is a required field`
        }),

    place: Joi.string()
        .min(6)
        .max(40)
        .required()
        .messages({
            'string.base': `"place" should be a type of 'text'`,
            'string.min': '"place" has to be least {#limit} characters.',
            'string.max': '"place" has to be max {#limit} characters.',
            'any.required': `"place" is a required field`
        })
});

eventSchema.validate({
    "title": "hi"
}, {
    "abortEarly": false
});

Joi 17.4 上validate()返回的error有一個名為details的屬性,您可以從中訪問有關這些錯誤的詳細信息(例如這些錯誤屬於哪些字段)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM