fabian-hiller / valibot

The modular and type safe schema library for validating structural data 🤖
https://valibot.dev
MIT License
6.12k stars 195 forks source link

Best way for validation optional strings #428

Closed brokuka closed 8 months ago

brokuka commented 8 months ago

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')
})
fabian-hiller commented 8 months ago

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)]),
]);
fabian-hiller commented 8 months ago

You can learn more about union here:

brokuka commented 8 months ago

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)

fabian-hiller commented 8 months ago

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.

brokuka commented 8 months ago

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

fabian-hiller commented 8 months ago

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/

brokuka commented 8 months ago

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

fabian-hiller commented 8 months ago

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.

brokuka commented 8 months ago

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"
      }
    }
fabian-hiller commented 8 months ago

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

brokuka commented 8 months ago

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

Thank you very much for your time.