Closed shossk closed 1 month ago
@devcaeg Thank you! I thought the way I was using Enum might be incorrect, but I believed that turning this into a Picklist or Enum wouldn’t directly solve the issue of handling error messages individually. I also checked the documentation, but it seemed there was no method to display error messages separately.
You can do it in these two ways, if I am not mistaken, you are on the right track.
enum EnumSchema {
ValueA = 'ValueA',
ValueB = 'ValueB',
ValueC = 'ValueC',
}
const Schema = object({
value: pipe(
enum_(EnumSchema),
check((input) => input === EnumSchema.ValueA),
check(
(input) => input !== EnumSchema.ValueB,
'Did you think it was ValueB?',
),
check(
(input) => input !== EnumSchema.ValueC,
'Why did you think it was ValueC?',
),
),
});
OR
const EnumSchema = ['ValueA', 'ValueB', 'ValueC'] as const;
const Schema = object({
value: pipe(
picklist(EnumSchema),
check((input) => input === 'ValueA'),
check((input) => input !== 'ValueB', 'Did you think it was ValueB?'),
check((input) => input !== 'ValueC', 'Why did you think it was ValueC?'),
),
});
Thanks for your help @devcaeg!
@devcaeg
const EnumSchema = ['ValueA', 'ValueB', 'ValueC'] as const;
const Schema = object({
value: pipe(
picklist(EnumSchema),
check((input) => input === 'ValueA'),
check((input) => input !== 'ValueB', 'Did you think it was ValueB?'),
check((input) => input !== 'ValueC', 'Why did you think it was ValueC?'),
),
});
If you do this, you will get the following message in the case of ValueB message: "Invalid input: Received \"ValueB\"", error should appear. Is there a cleaner answer?
Maybe what I'm looking for is something like zod's ZodErrorMap where you can customize the error message with return.
For some reason, I think the question is coming across as asking how to use Enum. What I want to know is not how to use Enum, but how to separate error messages from correct values when Enum is used. If you have difficulty understanding what I am saying, please let me know. I will describe it in more detail.
For example:
- Pass if it is ValueA
- Do not pass if it is ValueB, and display the error message “Did you think it was ValueB?”
- Do not pass if it is ValueC, and display the error message “Why did you think it was ValueC?”
If your schema only marks "ValueA"
as valid, there is no need for an enum. Check out this playground.
import * as v from 'valibot';
const Schema = v.object({
value: v.literal('ValueA', (issue) =>
issue.input === 'ValueB'
? 'Did you think it was ValueB?'
: issue.input === 'ValueC'
? 'Why did you think it was ValueC?'
: issue.message,
),
});
@fabian-hiller
Thank you very much! It looks like we can make it happen!
Ideally, I would like to use enum for literal as well, so that I can't do literal(“ValueD”), and I would like the completion of ValueB and ValueC to work for issue.input as well, is this possible?
Also, for future reference, what is in issue.message
?
The function in the above example is executed whenever the input is not "ValueA"
to generate the error message Valibot returns.
Also, for future reference, what is in
issue.message
?
This is the default error message that Valibot creates internally. It is used as a fallback in this schema for any other value.
Ideally, I would like to use enum for literal as well, so that I can't do literal(“ValueD”), and I would like the completion of ValueB and ValueC to work for issue.input as well, is this possible?
I do not fully understand you? Can you give an example or describe the behavior of the schema when different inputs are used?
@fabian-hiller
Sorry for the confusion, but I would like to solve the problem of issue.input
being unknown in this case, is it impossible?
const EnumSchema = ['ValueA', 'ValueB', 'ValueC'] as const;
const Schema = v.object({
value: v.pipe(
v.picklist(EnumSchema),
v.literal('ValueA', (issue) =>
issue.input === 'ValueB' // this issue.input type is unkwnon
? 'Did you think it was ValueB?'
: issue.input === 'ValueC'
? 'Why did you think it was ValueC?'
: issue.message,
)
),
});
Yes, this is possible, but I am not sure if it really makes sense to use picklist
or enum
in this case. Checkout this playground.
import * as v from 'valibot';
const Schema = v.object({
value: v.pipe(
v.picklist(['ValueA', 'ValueB', 'ValueC']),
v.value('ValueA', (issue) =>
issue.input === 'ValueB'
? 'Did you think it was ValueB?'
: 'Why did you think it was ValueC?',
),
),
});
@fabian-hiller @devcaeg Thank you very much. This will now be resolved. Thank you for responding to my question.
Hello, @fabian-hiller
I am very fond of Valibot and am very pleased that it can be integrated into various projects.
There is one thing I don't understand how to do, so I would appreciate it if you could help me.
I want to define an enum so that only certain values pass the check. For other values, I want to display different error messages based on the enum values. Is this possible?
For example:
That’s the kind of image I have in mind.
Here is the code that is close to what I tried.