react-hook-form: errors[name] with nested fields always returns undefined
Describe the bug
if name is something like myprop[0], errors[‘myprop[0]’] returns undefined, so the validation message cannot be shown.
<input name="chk[0]" ref={register({required:"This is required"})} />
in this case errors[‘chk[0]’] is undefined, but validation fails, so the form cannot be submitted and the error message cannot be displayed.
I have tried to provide a codesandbox but there is a nasty bug in codesandbox (https://github.com/codesandbox/codesandbox-client/issues/667) and it was impossible to make it work.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 18 (7 by maintainers)
Now you can import the utility function “get” directly from react-hook-form and use it like this :
I think I’m running into a similar type of issue (I’m upgrading from
react-hook-form@3.28to latest, haha). I had a reusable field component that usesFormContextand accesses a field’s errors similar to the examples in the docswhere name could be a nested value like
"user.firstName". In v3 this worked just fine because the errors object was flat, anderrors["user.firstName"]?.messagewas valid, however now I would need to access the property viaerrors.?user?.firstName?.messagevery explicitly, which I can’t generate dynamically 😢 (I don’t think, hopefully I’m just unaware of the fix 😅 ).I’m able to work around this using
lodash/getbut I was very happy earlier being able to fully use dynamic properties + TS + optional chaining with the flat errors. Example workaround (very gross because of the type casting)I absolutely love this library and it’s made things so much nicer than Redux-form / Formik, this is just a little nit since I feel dirty having to bring back lodash haha ❤️
Yeah I have something like this now (very quickly hacked together - and not very pretty)
You need to get single field error in fieldState in Controller render prop instead of formState errors object for all fields:
I truly do, it’s such a small nitpick in the face of so much goodness 😄
I read in #725 how I can leverage something like
useFormContext<MetaDataFormFields>()to have super strongly 💪 typederror.whatever.ayy.soNested?.messageaccess which sounds amazing for less generic/universal components that are specific to one form type. Awesome!Thanks @stern-shawn man it’s always a tradeoff…
to be honest, I love v3 flat errors, but then everyone are crying about the type-safe 😦 guess really i don’t have a choice rather than listen to the community, but 😃 i am going to export some of the utility functions from RHF, which include my tiny version of ‘get’ so you can skip using lodash if you want as well, (it’s on my todo list and it will come 😃
Hi @bluebill1049 thanks for the info. I cannot use optional chaining because I have written a custom error message component which receives the name (“aaa.bbb[0].xxx”) and errors object as props and renders default messages based on type if no message is specified in the instance.
I have solved it using a variation of this: https://stackoverflow.com/a/22129960/1524027 to parse the string and extract the error message.
I have discovered that errors object contains nested fields in a nested object structure, so
Wrong approach:
let err = errors[ 'prop[0].text' ]Correct approach:
let err = errors['prop'] && errors['prop'][0] && errors['prop'][0]['text']So it means that this is by design and not a bug. It is very confusing anyway because the name specified in the input component is a string (name=“prop[0].text”) and it is more logic to use the same string to find the error, but anyway. I think the documentation can be more explicit about this things.