Comments (9)
@kristianmandrup @ritchieanesco Hello guys! I have the same issue.
I made some debugging and it seems that the problem is related to src/types/mixed/mixed.js.
Here we have addMappedConstraints
function:
addMappedConstraints() {
const $map = this.constraintsMap;
const keys = Object.keys($map);
keys.map(key => {
const list = $map[key];
const fnName = key === "value" ? "addValueConstraint" : "addConstraint";
list.map(this[fnName]); <---- problem here
});
return this;
}
So for the required
constraint the addConstraint
function is executed.
addConstraint(propName, opts) {
const contraint = this.buildConstraint(propName, opts);
this.base = contraint || this.base;
return this;
}
As we can see, this function receives two parameters propName
('required' in our case) and opts
(0 in our case, because this function is executed as a callback of the list.map
).
Next both these parameters are passed to the buildConstraint
function:
buildConstraint(propName, opts = {}) { <--- here propName = 'required', opts = 0
let {
constraintName,
constraintValue,
propValue,
method,
yup,
value,
values,
errName
} = opts; <---- all the values in this object will be undefined
yup = yup || this.base; <---- yup = this.base
constraintValue =
constraintValue || propValue || this.constraints[propName]; <---- constraintValue = true
if (this.isNothing(constraintValue)) {
this.warn("no prop value");
return yup;
}
constraintName = constraintName || propName; <---- constraintName = 'required'
method = method || constraintName; <---- method = 'required'
const yupConstraintMethodName = this.aliasMap[method] || method; <---- yupConstraintMethodName = required
if (!yup[yupConstraintMethodName]) {
this.warn(`Yup has no such API method: ${yupConstraintMethodName}`);
return this;
}
const constraintFn = yup[yupConstraintMethodName].bind(yup);
const errFn =
this.valErrMessage(constraintName) ||
(errName && this.valErrMessage(errName)); <---- errFn = 'User is required'
!!! THIS BLOCK WONT BE EXECUTED IN OUR CASE
if (this.isPresent(values)) {
if (!Array.isArray(values)) {
this.warn(
"buildConstraint: values option must be an array of arguments"
);
return yup;
}
this.onConstraintAdded({ name: constraintName, value: values });
const newBase = constraintFn(values, errFn);
return newBase;
}
!!! THIS BLOCK WILL BE EXECUTED IN OUR CASE
if (this.isPresent(constraintValue)) {
this.onConstraintAdded({ name: constraintName, value: constraintValue });
const newBase = this.isPresent(constraintValue)
? constraintFn(constraintValue, errFn) <----- PROBLEM HERE
: constraintFn(errFn);
console.log('before add -> ', constraintValue, errFn);
console.log('on add -> ', constraintFn(errFn, constraintValue).tests)
console.log('newBase -> ', newBase.tests)
return newBase;
}
if (!this.isPresent(constraintValue)) {
this.onConstraintAdded({ name: constraintName });
const newBase = constraintFn(errFn);
return newBase;
}
this.warn("buildConstraint: missing value or values options");
return yup;
}
According to the fact that constraintValue
in our case is true
this.isPresent(constraintValue)
will return true
and constraintFn(constraintValue, errFn)
will be executed to determine newBase
.
Here constraintFn
function is equal to yup.string().required()
function that receives only one optional parameter message?: string | function
(https://github.com/jquense/yup).
The problem is that we pass constraintValue
(true
in our case) as a first parameter to yup.string().require()
that will set true
as a custom message.
So, newBase.tests
array will look like this:
newBase.tests -> [ { [Function: validate]
OPTIONS:
{ message: true, name: 'required', test: [Function: notEmpty] } },
{ [Function: validate]
OPTIONS:
{ message: true, name: 'required', test: [Function: hasLength] } } ]
@kristianmandrup I hope this info will be helpful and allow you to quickly resolve this issue.
from schema-to-yup.
Yeah, this whole part needs some love... in my latest branch I was extracting this part as a builder, cleaning up, refactoring and reworking it to be easier to manage and work with. I hope to get it sorted the coming weekend. Been too busy at work lately.
If you want to help out, have a look at constraint-builder branch
from schema-to-yup.
There are also a bunch of other branches with various refactoring, more tests etc
from schema-to-yup.
@kristianmandrup Cool! Thank you for your response. Will check other branches too. Can't wait for the next release
from schema-to-yup.
Cool :) I plan to work on it Friday and Saturday and make a 2.0 release on Sunday if all goes well. Regarding the required error, to fix it see how rules for email and url does it, I think
from schema-to-yup.
Hi @vsevolodbvd , I've spent all morning trying to fix the required issue as per this branch
Was behaving very weirdly, creating required tests (yup notEmpty
and hasLength
) no matter what.
When I test the behaviour in isolation (in required.test.js
) for the string
type (string schema tests) it works just fine and doesn't have this behaviour. I will try your suggestion now, avoiding message: true
Cheers.
from schema-to-yup.
I created the following test:
const userSchema = {
title: "users",
type: "object",
properties: {
username: { type: "string", required: true, email: true },
// last_name: { type: "string", required: false }
last_name: { type: "string" },
// nothing: {}, FAILS - type required
level: { type: "number" },
age: { type: "number", notRequired: true }
}
};
test.only("yup validates valid json to return true - error messages", done => {
try {
const yupSchema = buildYup(userSchema, {
err: msg => console.error(`ERROR: ${msg}`)
});
const { fields } = yupSchema;
console.log({ fields });
const { username, last_name, age, level, nothing } = fields;
console.log("username", username.tests);
console.log("last_name", last_name && last_name.tests);
console.log("age", age.tests);
console.log("level", level.tests);
console.log("nothing", nothing && nothing.tests);
yupSchema
.validate({
username: "mike"
})
.then(valid => {
console.log({ valid });
expect(valid).toBeTruthy();
done();
})
.catch(err => {
const { errors, name } = err;
console.log("ERRORS", { err, errors, name });
expect(errors[0]).toBeFalsy();
done();
});
} catch (e) {
console.error(e);
done();
}
});
As soon as you set type: "string"
it will create a yup.string()
property schema, which will have default rules to test that the property value is a valid string, ie. that it is not empty and has a length.
You explicitly have to add the constraint notRequired
for it to be ignored.
this.addConstraint(name, { method: 'notRequired, value: true })
convert() {
this.cleanConstraints();
// base constraints
}
cleanConstraints() {
// yeah, I know - but ugly or should be set in constructor as instance var
const propName = this.value.key;
this.addConstraint(propName, {
constraintName: "notRequired",
value: true
});
}
from schema-to-yup.
Check this: #33 (comment)
from schema-to-yup.
Finally solved it in latest release 1.9.10
- also added runtime mode
configuration
from schema-to-yup.
Related Issues (20)
- Get all properties under a schema HOT 1
- Custom error messages not having any effect HOT 4
- Custom message for type error HOT 18
- which version of yup does schema-to-yup support HOT 3
- "isNullable" is not working for Object type HOT 3
- Update yup to the newest 1.x version HOT 2
- Previously working required message, drops when combining refValueFor
- Previously working required message, drops when combining refValueFor HOT 1
- `ensure` on array does not work/missing example HOT 2
- Tests fail on fresh clone and install of dependencies HOT 3
- There is no regexp function that validate using a pattern which covers Unicode
- `TypeError: Cannot add property required, object is not extensible` on Node server using `esm` HOT 1
- Latest daft version `2020-12` is not supported HOT 2
- Question : why nullable and not type: ["null", ...] ? HOT 7
- Missing support for 'integer' HOT 11
- Multiple when causing Cyclic errors HOT 4
- TypeError: Invalid attempt to spread non-iterable instance.
- Custom 'required' error message doesn't work on fields with 'refValueFor' prop. HOT 1
- Unable to define type objects whichs default may be null
- yup.test
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from schema-to-yup.