When mapping errors inside transformErrors callback, I need to know the actual value of the input in question.
I need this to create a system for composing multiple existing formats into new composite formats. I want to match the input value against each of the "basic" formats and display the error for the one that fails. The allOf
method of composing formats unfortunately doesn't work for me, for reasons very specific to my project.
I tried injecting the form data into my tranformErrors
callback via currying and reading the data directly:
import _ from 'lodash'
import Form from '@rjsf/core'
const makeTransformErrors = formData => errors => {
errors.forEach(error => {
if (error.name === 'format') {
const value = _.get(formData, error.property)
// ...
}
})
}
const WrapedForm = (formData, ...rest) => {
const transformErrors = makeTransformErrors(formData)
return (
<Form
transformErrors={transformErrors}
formData={formData}
{...rest}
/>
)
}
but this way value
lags one keystroke behind the actual state of the form, which is what I was expecting. Unfortunately this doesn't work even when I don't pass formData
into makeTransformErrors
directly, but instead I pass in an object containing formData
and directly mutate it imeditately inside Forms onChange
, which I was expecting to work.
What are other possible ways of accessing the field's value? Maybe it could be possible to configure (or patch) ajv validator to attatch the value to validation error's params?
CodePudding user response:
Not sure exactly what kind of error validation you are trying todo, but have you tried using validate
?
It can be passed as such :
<Form .... validate={validate} />
where validate
is a function that takes as arguments formData
and errors
.
CodePudding user response:
Ok, I found a way of achieving what I want, but it's so hacky I don't think I want to use it. I can get the up-to-date value when combining the above mentioned prop mutation trick with using a getter for the message, postponing the evaluation until the message is actually read, which happens to be enough:
import _ from 'lodash'
import Form from '@rjsf/core'
const makeTransformErrors = formDataRef => errors => {
return errors.map(error => {
if (error.name !== 'format') return error
return {
...error,
get message() {
const value = _.get(propPath, formDataRef.current) // WORKS! But at what cost...
}
}
})
}
const WrapedForm = (formData, onChange, ...rest) => {
const formDataRef = React.useRef(formData)
const transformErrors = makeTransformErrors(formDataRef)
handleChange = (params) => {
formDataRef.current = params.formData
onChange(params)
}
return (
<Form
transformErrors={transformErrors}
onChange={handleChange}
formData={formData}
{...rest}
/>
)
}