YUP validation - how to get the value

Viewed 16491

I got the following piece of code :

    name: yup
      .string()
      .trim()
      .required(message("nameMissing"))
      .max(40, message("nameTooLongWithStatus", {
        length: (HERE I NEED HELP),
      })),

Refer to the line where I wrote "HERE I NEED HELP". I want it to be something like: name.toString().length

But this obviously doesnt work, actually nothing that I tried worked. I simply want to get the value of 'name' and get it's length, that is all.

So the idea is that, "name" should be a string with at most 40 characters. If it is more than 40, a message will be displyed saying "The maximum character count is 40 (current length)" where current length is the name you provided as input.

message("nameTooLongWithStatus" will accept a parameter "length" and will construct the said message.

3 Answers

You get these fields if you provide a function as a second argument to max().

path,value,originalValue,label,max

name: Yup.string()
.trim()
.max(5, (obj) => {
  const valueLength = obj.value.length;
  return `Name (length: ${valueLength}) cannot be more than ${obj.max}`;
})
.required('Required')

Not that easy, but you will need to use the .test method, do your own validation and call this.createError passing the message with the value you will receive from .test.

name: yup
  .string()
  .trim()
  .required(message("nameMissing"))
  .test('test_length_greater_than_40', '', function(value){
      // your condition
      if(value && value.toString().length > 40){
          // setting the error message using the value's length
          return this.createError({ message: `someErrorMessage ${value.toString().length}` })
      }
      return true
  }),

There is other ways of doing this too, like setting the params and getting it in the message (which is the second argument of test). If you want to do that way, you can take a look at the docs, but it's pretty much the same.

Also notice this from the docs

Please note that to use the this context the test function must be a function expression (function test(value) {}), not an arrow function, since arrow functions have lexical context.

You can make profit of the length's message second argument:

const schema = yup.object().shape({
  name: yup
    .string()
    .length(10, (elt)=> `${elt.originalValue ? elt.originalValue.length : "0" }`)
})

Then, if you validate:

await schema.validate(
  { name: "AAA" },
  {
    strict: false,
    abortEarly: false,
  }
);

You will get a ValidationError with the length of the input :

  Array [
    [ValidationError: 3],
  ]
Related