formik: [Next] Nested FieldArrays and setTouched not working together

Bug, Feature, or Question?

Bug

Current Behavior

When you have nested FieldArrays, let’s say the following path: questions.0.values.0.label where questions and values are the arrays and label is a regular input field. When onBlur is invoked on label, it wants to touch the path. But at that point (due to changing the values array) the current touched state is:

questions: 0: {form_question_type_id: true, values: true}

which causes the following error in setDeep:

Uncaught TypeError: Cannot create property '0' on boolean 'true'

which happens on the last line of this method: https://github.com/jaredpalmer/formik/blob/next/src/utils.ts#L69

Desired Behavior

It should update the touched state to a deep nested state like this:

questions: 0: {form_question_type_id: true, values: { label: true }}

Suggested Solutions

I’m not sure I understand the current implementation of setDeep. Why not just clone the object and use something like https://github.com/kalmbach/bury?

Info

  • Formik Version: 0.11.0-beta.1
  • OS: Mac OS High Sierra
  • Node Version: v9.4.0
  • Package Manager and version: Yarn v1.3.2

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 22 (10 by maintainers)

Commits related to this issue

Most upvoted comments

@elvisguillen So is your structure an array of array items? Trying to understand why you put value[0].

@jaredpalmer Is the documentation updated? Trying to find out how touched is being handled for an array of objects.

why not stick with lodash and use set which works for bracket notation AND dot notation…

@jaredpalmer I still get the error, when I leave the text box. Do I have to do something in code to dodge this error:

formik.es6.js:5556 Uncaught TypeError: Cannot create property ‘0’ on boolean ‘true’

Here is a code snippet:

<FieldArray
      name="friends"
      render={arrayHelpers => (
        <Form>
          <h3>Name</h3>
          <input
            name="name"
            type="text"
            value={values.name}
            onChange={handleChange}
            onBlur={handleBlur}
          />
          {values.friends && values.friends.length > 0 ? (
            values.friends.map((friend, index) => (
              <div>
                <MySelect
                  name={`friends.${index}.type`}
                  value={`friends.${index}.type`}
                  onChange={setFieldValue}
                  current={{ curVal: values.friends, index }}
                  options={[
                    { value: "single_text", label: "Single Line Text" },
                    { value: "multi_select", label: "Multi Select" }
                  ]}
                  onBlur={setFieldTouched}
                />

                {
                  values.friends[index] &&
                  <Field name={`friends.${index}.name`} />

It happens in the Field Component

I figured it out! Will open a PR

Working on a fix now.