admin管理员组文章数量:1392068
So this is fairly strange and I can't understand where it's ing from.
I have a signup WS (in Node.js using Sales.js) where the minimum required age is 18 years old, the validation is done by Yup.
This is my yup schema:
const yup = require('yup');
const moment = require('moment');
const birthdate = yup.date()
.typeError('INVALID_DATE')
.min(moment().subtract(115, 'years'), 'MIN_AGE')
.max(moment().endOf('day').subtract(18, 'years'), 'MAX_AGE');
module.exports = {
birthdate
};
So this is fairly strange and I can't understand where it's ing from.
I have a signup WS (in Node.js using Sales.js) where the minimum required age is 18 years old, the validation is done by Yup.
This is my yup schema:
const yup = require('yup');
const moment = require('moment');
const birthdate = yup.date()
.typeError('INVALID_DATE')
.min(moment().subtract(115, 'years'), 'MIN_AGE')
.max(moment().endOf('day').subtract(18, 'years'), 'MAX_AGE');
module.exports = {
birthdate
};
As you can see from the example underneath, when I put today's date, it is paring it to 2002-07-31
while it's supposed to be pared with moment().endOf('day').subtract(18, 'years')
which would be 2002-08-12
Note that 2002-07-31
is the date in which I built the project. So if I repile it now, I will no longer have that problem for today. If I retest tomorrow, it will pare it with today’s date!
I have no idea how is this possible or how to fix it.
This is the error from yup:
"errors": [{
"field": "birthdate",
"code": "E_MAX_AGE_BIRTHDATE",
"params": {
"path": "birthdate",
"value": "2002-08-12T10:00:00.000Z",
"originalValue": "2002-08-12T10:00:00.000Z",
"max": "2002-07-31T21:59:59.999Z"
}
}]
Any ideas?
Versions used: moment 2.24.0
; yup 0.29.2
2 Answers
Reset to default 3For anyone wanting a simpler way to have a dynamic date (e.g. now) that is evaluated at the moment of validation (e.g. not the time at build date): use yup.lazy().
The below example will check the min date is later than the max date (and vice versa), with a dynamic max date that is freshly generated on each validation attempt.
import { date, lazy, object, ref } from 'yup'
function getMinDate() {
return new Date(2000, 1, 1)
}
function getMaxDate() {
return new Date()
}
const schema = object({
minDate: date()
.min(getMinDate(), `Min start date is ${getMinDate()}`)
.max(ref('maxDate'), 'Min date must be earlier than the max date'),
maxDate: lazy(() => date()
.min(ref('minDate'), 'Max date must be later than min date')
.max(getMaxDate(), `Max start date is ${getMaxDate()}`)
)
})
Okay so I found the solution.
As a matter of a fact, Yup will store the date you initially gave and pile it. It will no longer execute moment().endOf('day').subtract(18, 'years')
each time you validate a date.
For this, you have to use a test method, not min
nor max
.
I have created an extension method to yup.date
as following:
/**
* This function is used to format the error like date.min does
*/
function customValidationError(errorMessage, value, path, extraData) {
const error = new yup.ValidationError(errorMessage,
value,
path);
error.params = {
path: path,
value: value,
originalValue: value,
...extraData
};
return error;
}
/**
* Extension method to yup.date
* You should pass a function that will be executed each time you want to check again the current date.
* @name yup.dynamicMaxDate
* @global yup.dynamicMaxDate
*/
yup.addMethod(yup.date, 'dynamicMaxDate', function(path, errorMessage = 'MAX_DATE', maxDateFunction) {
return this.test(path, errorMessage,
(value) => {
const maxDate = maxDateFunction();
return new Promise((resolve, reject) => {
const error = customValidationError(errorMessage, value, path, {
max: maxDate
});
value && moment(value).isAfter(maxDate) ?
reject(error) :
resolve(true);
});
});
});
/**
* Extension method to yup.date to check if date is before a given date
* You should pass a function that will be executed each time you want to check again the current date.
* @name yup.dynamicMinDate
* @global yup.dynamicMinDate
*/
yup.addMethod(yup.date, 'dynamicMinDate', function(path, errorMessage = 'MIN_DATE', minDateFunction) {
return this.test(path, errorMessage,
(value) => {
const minDate = minDateFunction();
return new Promise((resolve, reject) => {
const error = customValidationError(errorMessage, value, path, {
min: minDate
});
value && moment(value).isBefore(minDate) ?
reject(error) :
resolve(true);
});
});
});
And to use those methods:
const birthdate = yup.date()
.typeError('INVALID_DATE')
// Note tham I'm passing a function to be executed when validating date
.dynamicMinDate('birthdate', 'MIN_AGE', () => {
return moment().startOf('day').subtract(115, 'years').toDate();
})
.dynamicMaxDate('birthdate', 'MAX_AGE', () => {
return moment().endOf('day').subtract(18, 'years').toDate();
});
本文标签: javascriptYup compares min max date with build date instead of current dateStack Overflow
版权声明:本文标题:javascript - Yup compares min max date with build date instead of current date - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744768503a2624191.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论