添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
英俊的猴子  ·  Frequently Asked ...·  昨天    · 
怕考试的熊猫  ·  JSON | Grafana k6 ...·  19 小时前    · 
不羁的风衣  ·  Configuring the ...·  7 小时前    · 
爱逃课的牛排  ·  数据库 - ...·  2 年前    · 

Yup is a super popular object validation library written in TypeScript.

This post will assume a basic working knowledge of Yup.

Not only does Yup provide a large array of built-in validation functions, but it also allows users to customize tests to suit their needs. These custom test functions accept an options object, which allows for external values to be passed in to be used in writing the boolean logic within the test.

On the documentation page, they give this example:

const jamesSchema = string().test({
    name: 'is-james',
    message: (d) => `${d.path} is not James`,
    test: (value) => value == null || value === 'James',
jamesSchema.validateSync('James'); // "James"
jamesSchema.validateSync('Jane'); // ValidationError "this is not James"
    Enter fullscreen mode
    Exit fullscreen mode

But what if the name to be tested is not "James"? What if we want to pass in a name against which to validate? Well, the validate and validateAt functions, as well as their sync alternatives accept an options object, which can include external values. The options object is included as part of the context object passed to the body of the test function. More info here.

If we adjust the previous example, we can pull the name out of the context options object within the test function.

const nameSchema= string().test({
    name: 'is-name',
    message: (d) => `${d.path} is not James`,
    test: (value, context) => (
      value !== null &&
      value === context.options.targetName
    Enter fullscreen mode
    Exit fullscreen mode

This will throw a ValidationError with the message this is not James. However, the name "James" is hardcoded into the error message and has no relation to the target value stored in context.options.targetName.

If we log the value of context within the test function, it looks like this:
"path": "", "type": "is-name", "options": { "targetName": "Ringo", "sync": true "originalValue": "James", "schema": { // ...excluded for brevity Enter fullscreen mode Exit fullscreen mode

As we can see, the targetName property is included in the options object within the context object.

However, if we log the object that's passed to the message function, we see something different.
"value": "James", "originalValue": "James", "path": "this", "spec": { "strip": false, "strict": false, "abortEarly": true, "recursive": true, "nullable": false, "optional": true, "coerce": true Enter fullscreen mode Exit fullscreen mode

Uh-oh, the options object isn't included in the object passed to the message function. So, what do we do if we need to pass a value through the context object to be used in the error message?

Well, the solution is to forego use of the message function entirely. The context object in the test function has a createError function which can be used to format a Yup ValidationError message. The result of this function can be returned if the resulting boolean from the test function is false and because it is in the scope of the test function, it still has access to the context values passed to the function.

const nameSchema = string().test({
    name: 'is-name',
    test: (value, context) => (
      value !== null &&
      value === context.options.targetName
    ) || context.createError(`${context.path} is not ${context.options.targetName}`),
    Enter fullscreen mode
    Exit fullscreen mode

Now the target name value will be formatted into the resulting ValidationError message.

Here's a working example.

It would be great if the context object would be passed to the message function as well. It would simplify the error-handling logic and isolate it from the test logic. There is an open issue on Yup's Github page about this, so hopefully it'll get resolved in an upcoming update release.

Connecting Stripe Webhooks to Firebase Cloud Functions on localhost using Localtunnel. #firebase #stripe #javascript #react

Built on Forem — the open source software that powers DEV and other inclusive communities.

Made with love and Ruby on Rails. DEV Community © 2016 - 2025.