Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use react-hook-form for nested array

I am trying to use react hook form to create nested arrays. I have attached a sandbox with my sample code

Code Snippet

<ul>
        {fields.map((item, index) => {
          return (
            <li key={item.id}>
              <label> single input </label>
              <input
                name={`test[${index}].task`}
                ref={register()}
                defaultValue={item.task}
              />
              <br />
              <label> first Name </label>
              <input
                name={`test[${index}].name.first`}
                ref={register()}
                defaultValue={item.name.first}
              />
              <br />
              <label>last Name </label>
              <input
                name={`test[${index}].name.last`}
                ref={register()}
                defaultValue={item.name.last}
              />
              <br />

              <label>First Nested </label>
              <input
                name={`test[${index}].nestedArray[${index}].firstNested`}
                ref={register()}
                // defaultValue={item.nestedArray.nested}
              />

              <br />
              <label> Second Nested </label>
              <input
                name={`test[${index}].nestedArray[${index}].secondNested`}
                ref={register()}
                // defaultValue={item.nestedArray.nested}
              />
              <br />

              <button type="button" onClick={() => remove(index)}>
                Delete
              </button>
            </li>
          );
        })}
      </ul>

Issue

The initial step works fine. I am able to get the data in the "nestedArray". but when I append for more than one nested array my data. My "nestedArray" always starts with a "null" the "null" continues to add if I append for more. How can I avoid this "null" value? I do not want to retain previous input. I want to avoid the null value completely.

Sample output

{
   "test":[
      {
         "task":"single",
         "name":{
            "first":"Jack",
            "last":"Box"
         },
         "nestedArray":[
            {
               "firstNested":"firstNested",
               "secondNested":"firstSecondNested"
            }
         ]
      },
      {
         "task":"Second",
         "name":{
            "first":"Kate",
            "last":"Smith"
         },
         "nestedArray":[
            **null,**
            {
               "firstNested":"SecondNested",
               "secondNested":"SecondNestedSecond"
            }
         ]
      }
   ]
}

Expected Sample output

{
   "test":[
      {
         "task":"single",
         "name":{
            "first":"Jack",
            "last":"Box"
         },
         "nestedArray":[
            {
               "firstNested":"firstNested",
               "secondNested":"firstSecondNested"
            }
         ]
      },
      {
         "task":"Second",
         "name":{
            "first":"Kate",
            "last":"Smith"
         },
         "nestedArray":[
            {
               "firstNested":"SecondNested",
               "secondNested":"SecondNestedSecond"
            }
         ]
      }
   ]
}

Steps to reproduce in Sandbox

  1. click on append
  2. provide details
  3. See data in console
  4. Click on append(again) to add another set of data
  5. Console will show "null" inside the nestedArray.

References

Code Sandbox

Code Snippet

<ul>
        {fields.map((item, index) => {
          return (
            <li key={item.id}>
              <label> single input </label>
              <input
                name={`test[${index}].task`}
                ref={register()}
                defaultValue={item.task}
              />
              <br />
              <label> first Name </label>
              <input
                name={`test[${index}].name.first`}
                ref={register()}
                defaultValue={item.name.first}
              />
              <br />
              <label>last Name </label>
              <input
                name={`test[${index}].name.last`}
                ref={register()}
                defaultValue={item.name.last}
              />
              <br />

              <label>First Nested </label>
              <input
                name={`test[${index}].nestedArray[${index}].firstNested`}
                ref={register()}
                // defaultValue={item.nestedArray.nested}
              />

              <br />
              <label> Second Nested </label>
              <input
                name={`test[${index}].nestedArray[${index}].secondNested`}
                ref={register()}
                // defaultValue={item.nestedArray.nested}
              />
              <br />

              <button type="button" onClick={() => remove(index)}>
                Delete
              </button>
            </li>
          );
        })}
      </ul>
like image 875
Jodi Avatar asked Oct 14 '22 22:10

Jodi


1 Answers

Let me know if this works. Maybe you didnt need to index the nestedArray since its been mapped. It worked in the console for me without the null. I think since you already targetted "test" with:

`test[${index}].nestedArray.firstNested`

you might not need to index the nestedArray also?

      <ul>
        {fields.map((item, index) => {
          return (
            <li key={item.id}>
              <label> single input </label>
              <input
                name={`test[${index}].task`}
                ref={register()}
                defaultValue={item.task}
              />
              <br />
              <label> first Name </label>
              <input
                name={`test[${index}].name.first`}
                ref={register()}
                defaultValue={item.name.first}
              />
              <br />
              <label>last Name </label>
              <input
                name={`test[${index}].name.last`}
                ref={register()}
                defaultValue={item.name.last}
              />
              <br />

              <label>First Nested </label>
              <input
                name={`test[${index}].nestedArray.firstNested`} //removed index
                ref={register()}
                // defaultValue={item.nestedArray.nested}
              />

              <br />
              <label> Second Nested </label>
              <input
                name={`test[${index}].nestedArray.secondNested`} //removed index
                ref={register()}
                // defaultValue={item.nestedArray.nested}
              />
              <br />

              <button type="button" onClick={() => remove(index)}>
                Delete
              </button>
            </li>
          );
        })}
      </ul>
like image 145
twominds Avatar answered Oct 18 '22 08:10

twominds