fabian-hiller / valibot

The modular and type safe schema library for validating structural data 🤖

Home Page:https://valibot.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Best way for validation optional strings

brokuka opened this issue · comments

What is the best way to write string validation if it is only needed if there is something in the input, and when the user clears the field, then the validation should disappear because it is optional. Validation is used with vee-validate.

const firstStepSchema = toTypedSchema(
  object({
    surname: optional(
      string([toTrimmed(), minLength(INPUT_MIN_LENGTH, MIN_FULL_NAME_ERROR_MESSAGE.SURNAME), maxLength(INPUT_MAX_LENGTH, MAX_FULL_NAME_ERROR_MESSAGE.SURNAME)]),
    ),
  }),
)

My solution

watchEffect(() => {
  if (isFieldDirty('surname') && values.surname === '')
    resetField('surname')
})

I am not entirely sure that I understand your use case, but I would write the schema this way:

import * as v from 'valibot';

const Schema = v.union([
  v.literal(''),
  v.string([v.minLength(5), v.maxLength(15)]),
]);

I am not entirely sure that I understand your use case, but I would write the schema this way:

import * as v from 'valibot';

const Schema = v.union([
  v.literal(''),
  v.string([v.minLength(5), v.maxLength(15)]),
]);

It's not quite the same. Issue is when types is changing, initially input has undefined type and when user enters type changing to string. Here is repro (click)

Can you explain what is wrong with this approach? The code seems to work fine. It is normal for a form schema to set a property to string even if it is initially undefined.

Can you explain what is wrong with this approach? The code seems to work fine. It is normal for a form schema to set a property to string even if it is initially undefined.

Validation messages are not what is needed, if you click on the input and do not write anything, validation will work

You might want to change your schema to the following:

import * as v from 'valibot';

const Schema = v.optional(
  v.union([v.literal(''), v.string([v.minLength(5), v.maxLength(15)])]),
  ''
);

Or you should control it through your form library by adding default values or changing the time when the validation happens.

You can read more about optional values here: https://valibot.dev/guides/optionals/

You might want to change your schema to the following:

import * as v from 'valibot';

const Schema = v.optional(
  v.union([v.literal(''), v.string([v.minLength(5), v.maxLength(15)])]),
  ''
);

Or you should control it through your form library by adding default values or changing the time when the validation happens.

You can read more about optional values here: https://valibot.dev/guides/optionals/

Sorry for such a late response, this option works partially, the problem with messages remains, instead it shows Invalid type. Updated repro: https://stackblitz.com/edit/nuxt-starter-lcbmm9?file=app.vue,nuxt.config.ts

Sorry for such a late response, this option works partially, the problem with messages remains...

What version of Valibot are you using? I think we have fixed this in a newer version. Please upgrade to the newest version and try it again.

Sorry for such a late response, this option works partially, the problem with messages remains...

What version of Valibot are you using? I think we have fixed this in a newer version. Please upgrade to the newest version and try it again.

It's library from vee-validate..

"node_modules/@vee-validate/valibot": {
      "version": "4.12.5",
      "resolved": "https://registry.npmjs.org/@vee-validate/valibot/-/valibot-4.12.5.tgz",
      "integrity": "sha512-T3iqo37hgyK88qpsEoIZw89qMnnJGc8DrJdotH93avvUP793KBq7+K0OIKJZb+xYSsOeF9cFsJ5gLT0WTAHjMg==",
      "dependencies": {
        "type-fest": "^4.8.3",
        "valibot": "^0.24.1",
        "vee-validate": "4.12.5"
      }
    }

Try to add Valibot yourself in the latest version. This will fix your problem.

Try to add Valibot yourself in the latest version. This will fix your problem.

Thank you very much for your time.