react-hook-form: [REQ] Ability to return form and field level errors from submission

Is your feature request related to a problem? Please describe. This is a feature request for being able to pass the form errors from a submission.

Describe the solution you’d like I would like to see the callback passed to handleSubmit be able to handle being returned an object of errors that could be merged into the existing errors object. Including a special case for an overall form-level error.

Describe alternatives you’ve considered I tried manually implementing something like this and it requires a lot of work from the implementer’s side.

/cc @bluebill1049 @barrymay

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 1
  • Comments: 40 (36 by maintainers)

Commits related to this issue

Most upvoted comments

This is a great library, but a little criticism, the more Wishlist is implemented, the more difficult it is to maintain and develop the library, I paid attention to the number of bug fixes for the whole time. Also, in my case, errors are returned in a different format, it depends on the server, and it is easier for me to call SetError than to convert to a different format, in general, a very narrow case.

I like that the library is really small and has a unique approach to form control, I would not want it to become a Swiss knife. Maybe it’s better to have a Cookbook?

@bluebill1049 You can revert that code for now and we can continue the discussion.

Hmm, I suppose I could build this out as a helper in my apps.

const applySubmissionErrors = callback => data => {
	const response = await callback(data)
	if (response && response.errors) {
		Object.entries(response.errors).forEach(([name, error]) => {
			setError(name, error)
		})
	}
}

Just seems like it would be easier to have in the lib and a nice DX win.

@JeromeDeLeon What other setters are you passing? Would it be easier to remove the wrapping function and just return an error object?

and having just re-looked at this code, I’ve realised that typing the setFormErrors function above is futile, because TypeScript doesn’t provide runtime type safety. Also where the types are provided by the library, just pull them in… doh! 🤦🏻‍♂️

Update to snippet from above:

import { UseFormMethods } from 'react-hook-form';
/**
 * A function that maps all API error responses to inputs using RHF `setError`
 * @param setError RHF set error function passed in as a callback
 * @param errors Errors object returned from the API
 */
export function setFormErrors(
  setError: UseFormMethods['setError'],
  errors: Record<string, string>
) {
  for (const error in errors) {
    setError(error, {
      type: 'server',
      message: errors[error],
    });
  }
}

@stramel maybe we just stick with setError for now?

oh you are right about that! going to fix that! thanks

Hmm I’m not sure it will be as obvious to some developers that they will need to return

{
	password: {
		message: 'error'
	}
}

Maybe we could just set the type differently manually? setError(name, error, 'submissionError').

You could potentially do a check like:

if (isObject(error)) {
	const { message, type } = error
	setError(name, message, type)
} else {
	setError(name, error, 'submissionError')
}

@bluebill1049 WDYT about using this to ensure the same error object? instead of just spreading the errors?

Object.entries(response.errors).forEach(([name, error]) => {
  setError(name, error)
})

@stramel, setStatus in const [status, setStatus] = useState({ }); for other things I want to do in my form like successfully detecting if It successfully submitted or not.

what’s your thoughts on this @barrymay ? I personally don’t mind it, it makes server validation simpler, you don’t have to manually call setError.

I don’t think so. I don’t have any use case for it that want me to use the return errors feature cuz like I said, I came from formik that didn’t have that. Maybe for others 👍

@bluebill1049 I think setError would work for the form-level error. Although, I like the DX of being able to return the object from the submission callback. Especially since in my case the submit function is coming from outside the function with the form.

I think it would be a minimal addition to the handleSubmit with a good DX trade-off.

In my use case,

const submit = data => {
   callSubmit(data, {
    setErrors,
    reset,
    otherSetters
   }
}

<form onSubmit={handleSubmit(submit)>
...
</form>

just sharing 😉

Shoot forgot to mention that I didn’t test how this worked with nested naming

That’s what I was thinking. If we want, it could be limited to registered fields.

sure i can take a look at that