New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Correctly return nullable data in matchedData
#1175
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Reading the issue you reported, it seems you're mostly worried with the undefined values coming along?
It's a bit tough to find a way out without a breaking change.
One thing I'm thinking is to make includeOptionals
accept a string value, e.g. ignoreUndefined
(or something less wordy). So it carries everything but values that were really not set.
WDYT?
data[0].value = null; | ||
data[1].value = undefined; | ||
|
||
context = new ContextBuilder().setOptional({ checkFalsy: false, nullable: true }).build(); | ||
context.addFieldInstances(data); | ||
|
||
expect(context.getData({ requiredOnly: true })).toEqual([]); | ||
expect(context.getData({ requiredOnly: true })).toEqual([data[0]]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a breaking change, and it also doesn't make much sense:
Why would you want a field that's been marked as optional to be included when its value matches such definition, and you specified requiredOnly: true
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because right now requiredOnly
actually does return optional data when the value is say an Int
. So by your logic - that should actually not be returned as the Int was marked as optional and you passed requiredOnly. So I could argue the current logic is already breaking that contract. What my change does is allow null
s to come through when you specifically say you want to allow nulls ie: nullable: true
. Nearly identical to saying you want to allow optional Ints and having those come back when requiredOnly
is true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not quite. Perhaps the APIs are not very good here, but this behaviour shouldn't change IMO.
The value it has must match the definition of optional. That is, one of
undefined
(default behaviour)null
orundefined
(nullable: true
)- falsy (
checkFalsy: true
-- I don't like this name much tbh, it's express-validator v2 inheritance)
If your integer is optional but has value of 1, then it's considered as passed in the request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have the same problem.
I think it's more accurate to keep keys in both request body and validation schema in matchedData
return value too.
But of course, it's a breaking change.
How about add another parameter to matchedData function to keep optional keys which exist in request body?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the overall issue we are having is there is no good way to support a type like: type Body = {
age: number | null
} Right now in express-validator we would attempt to do: check('age').optional({ nullable: true }).isInt() But this isn't really describing what we want, and I guess my PR is abusing that trying to get this to work (and I think other people are also trying to get this same behavior to work). In reality we want an API like: check('age').isInt({ nullable: true }) This exactly describes what we're looking for. To be honest I have no clue what the current |
Here's best example of how the current behavior is broken. You are claiming I made a breaking change by returning the null value when |
3177f64
to
6e160b1
Compare
Default behaviour of |
I agree with you if |
Description
Correctly return nullable data in
matchedData
: #1048To-do list