11

I am using formik for the forms. In my form, I need to use the concept of FieldArray and it's a nested one. I could not fill the nested forms with respective values. Here is how I have done

const Itinerary = ({ itineraries, push, remove }) => {
  return (
    <>
      <Heading>Itinerary</Heading>
      {itineraries && itineraries.length === 0 && (
        <span
          style={{
            color: theme.color.primary,
            padding: "0 10px",
            cursor: "pointer"
          }}
          onClick={() => push({})}
        >
          +
        </span>
      )}
      {itineraries &&
        itineraries.length > 0 &&
        itineraries.map((day, index) => {
          return (
            <React.Fragment key={index}>
              <Row key={index} style={{ alignItems: "center" }}>
                <Text>
                  How many
                  <DaysField
                    component={TextField}
                    name={`itineraries.${index}.days`}
                    placeholder="days"
                    normalize={val => val && parseInt(val)}
                  />
                  of itinerary?
                </Text>
                {itineraries && itineraries.length - 1 === index && (
                  <>
                      <Button>
                        <Button.Round onClick={() => push({})}>+</Button.Round>
                      </Button>
                      <Button>
                        <Button.Round onClick={() => remove(index)}>
                          -
                        </Button.Round>
                      </Button>
                  </>
                )}
              </Row>
              <FieldArray
                name={`itineraries.${index}.itinerary`}
                render={({ push, remove }) => (
                  <>
                    <Heading>
                      Fill up itinerary
                      {itineraries[index].itinerary &&
                        itineraries[index].itinerary.length === 0 && (
                          <span
                            style={{
                              color: theme.color.primary,
                              padding: "0 10px",
                              cursor: "pointer"
                            }}
                            onClick={() => push({})}
                          >
                            +
                          </span>
                        )}
                    </Heading>
                    {itineraries[index].itinerary &&
                      itineraries[index].itinerary.length > 0 &&
                      itineraries[index].itinerary.map((i, idx) => {
                        console.log(
                          "itinerary index",
                          itineraries[index].itinerary[idx]
                        );
                        return (
                          <React.Fragment>
                            <Row
                              style={{
                                alignItems: "center",
                                alignSelf: "center"
                              }}
                            >
                              <Col xs={12} md={3}>
                                <Field
                                  component={TextField}
                                  placeholder="Day"
                                  name={`${itineraries[index].itinerary[idx]}.day`}
                                />
                              </Col>
                              <Col xs={12} md={3}>
                                <Field
                                  component={TextField}
                                  placeholder="Description"
                                  name={`${itineraries[index].itinerary[idx]}.description`}
                                />
                              </Col>
                              <Col xs={12} md={3}>
                                <Field
                                  component={TextField}
                                  placeholder="Overnight"
                                  name={`${itineraries[index].itinerary[idx]}.overnight`}
                                />
                              </Col>
                              <Col xs={12} md={2}>
                                <Field
                                  component={TextField}
                                  placeholder="Altitude"
                                  name={`${itineraries[index].itinerary}.altitude`}
                                  normalize={value => {
                                    return value && parseFloat(value);
                                  }}
                                />
                              </Col>
                              <Col xs={12} md={1}>
                                {itineraries &&
                                  itineraries.length - 1 === index && (
                                    <>
                                      <ActionBtn>
                                        <Button>
                                          <Button.Round
                                            onClick={() => push({})}
                                          >
                                            +
                                          </Button.Round>
                                        </Button>
                                        <Button>
                                          <Button.Round
                                            onClick={() => remove(index)}
                                            color={theme.color.red}
                                          >
                                            -
                                          </Button.Round>
                                        </Button>
                                      </ActionBtn>
                                    </>
                                  )}
                              </Col>
                            </Row>
                          </React.Fragment>
                        );
                      })}
                  </>
                )}
              />
            </React.Fragment>
          );
        })}
    </>
  );
};

The itineraries initialValues looks like this

itineraries: [
                {
                  days: 1,
                  itinerary: [
                    {
                      day: "Day 1",
                      description: "description",
                      overnight: "overnight info",
                      altitude: 150.5
                    },
                    {
                      day: "Day 2",
                      description: "description 2",
                      overnight: "overnight info",
                      altitude: 150.5
                    }
                  ]
                }
              ]

Only Nested part is not working. Can anyone help me at this, please?

1 Answer 1

13

You problem is in how you pass the name for the component:

name={`${itineraries[index].itinerary[idx]}.overnight`}

This way, what you are doing is passing the value of itineraries[index].itinerary[idx] to a string.

What you should do is pass that as a string, not it's value:

name={`itineraries[${index}].itinerary[${idx}].overnight`}

This way, only the indexes get the value printed, which is correct.

Here is the difference

${itineraries[index].itinerary[idx].overnight will return [object Object].overnight because you are access the value of itineraries[index].itinerary[idx] and it's calling .toString().

But itineraries[${index}].itinerary[${idx}].overnight will return itineraries[0].itinerary[0].overnight which is a valid formik string and it can get it's value.

Sign up to request clarification or add additional context in comments.

1 Comment

In the same case how do I use remove(idx) to remove nested arrays field? I tried but it removes the last field

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.