hello, I'm using YUP to validate form values within withFormik... my question is I need to i18n the invalid message from YUP, I don't know how to get the injected Intl prop from react-intl. any examples on this? thanks in advance.
const formInstance = withFormik<IFormProps, IFormValues>({
mapPropsToValues: ({ name, description }) => ({
name: name || "",
description: description || ""
}),
validationSchema: yup.object().shape({
name: yup
.string().trim()
.min(1,'message need to be i18n') //i dont know how to get the 'Intl' props from react-intl
.max(25,'message need to be i18n'),
description: yup.string().trim().max(50,'message need to be i18n')
}),
handleSubmit: (values, { resetForm, setSubmitting }) => {
setTimeout(() => {
console.log("submitted!", values);
resetForm();
setSubmitting(false);
}, 1000);
}
})(injectIntl(ProjectCreateForm));
Read API docs more carefully, validationSchema?: Schema | (() => Schema).
validationSchema could be a function.
Personally I pass i18n string/code/whatever as yup error message.
Then, where you render an error in a React component, you can put this i18n code into Reactintl component.
Hola! So here's the deal, between open source and my day job and life and what not, I have a lot to manage, so I use a GitHub bot to automate a few things here and there. This particular GitHub bot is going to mark this as stale because it has not had recent activity for a while. It will be closed if no further activity occurs in a few days. Do not take this personally--seriously--this is a completely automated action. If this is a mistake, just make a comment, DM me, send a carrier pidgeon, or a smoke signal.
ProBot automatically closed this due to inactivity. Holler if this is a mistake, and we'll re-open it.
Personally I pass i18n string/code/whatever as yup error message.
Then, where you render an error in a React component, you can put this i18n code into Reactintl component.
Your solution is great! THX.
How do you handle params in that case? There's no way I can find to get the parameters once it gets to the Formik <ErrorMessage> component.
Here's my gross workaround, which is working, at least so far.
I'm using react-intl.
My requirement is to get an error code (to use as translation key) and any relevant parameters through to react-intl. But yup/formik doesn't pass through the parameters, only the message after parameters are substituted into the placeholders. It won't substitute in any parameters unless the error message is a string.
So how about...
yup.setLocale({
string: {
default: JSON.stringify({
id: 'form.error.string.default',
defaultMessage: 'This value is invalid',
values: { path: '${path}' },
}),
email: JSON.stringify({
id: 'form.error.string.email',
defaultMessage: 'This must be an email address',
values: { path: '${path}' },
}),
min: JSON.stringify({
id: 'form.error.string.min',
defaultMessage: 'Minimum length is {min}',
values: { path: '${path}', min: '${min}' },
}),
},
mixed: {
required: JSON.stringify({
id: 'form.error.required',
defaultMessage: 'This field is required',
values: { path: '${path}' },
}),
},
})
yup.addMethod(yup.string, 'equalTo', (ref, msg) =>
yup.mixed().test({
name: 'equalTo',
exclusive: false,
message: msg || JSON.stringify({
id: 'form.error.string.equal-to',
defaultMessage: 'Field {path} must be equal to {reference}',
values: { path: '${path}', reference: '${reference}' },
}),
params: {
reference: ref.path,
},
test: function(value) {
return value === this.resolve(ref)
},
})
)
and so on. Since it's stringified, the ${paramname} parts get the values substituted in, which yields a values object with the parameters. (Note that they're then always strings, never integers or booleans. For messages this shouldn't pose a problem, I think.)
Then, a renderer component for Formik's <ErrorMessage>:
import React from 'react'
import { FormattedMessage } from 'react-intl'
import { ErrorMessage as FormikErrorMessage } from 'formik'
const Message = ({ children }) => {
try {
const data = JSON.parse(children)
if (data.id != null) {
return <FormattedMessage {...data} />
}
} catch {
// Couldn't parse as JSON; do nothing
}
return <FormattedMessage id={children} defaultMessage={children} />
}
const ErrorMessage = props => <FormikErrorMessage {...props} component={Message} />
export default ErrorMessage
It works. But it's pretty nasty.
Very much hoping I've missed some really obvious nicer way to do this. Please enlighten me if so!
Most helpful comment
Personally I pass i18n string/code/whatever as yup error message.
Then, where you render an error in a React component, you can put this i18n code into Reactintl component.