2

I am new to React and Formik and still trying to learn how to use it. I am trying to map items from an array of items. However, I am not sure what the proper syntax is for the mapping. I get the following error:

"TypeError: Cannot read property 'map' of undefined"

This is the InitialValues:

{
    "costs": [{
        "cost_Id": 1,
        "investment_Plan_Id": 1,
        "item": "abc",
        "amount": "3",
        "unit_Cost": "444"
    }, {
        "cost_Id": 2,
        "investment_Plan_Id": 1,
        "item": "xyz",
        "amount": "4",
        "unit_Cost": "99"
    }, {
        "cost_Id": 3,
        "investment_Plan_Id": 1,
        "item": "fff",
        "amount": "33",
        "unit_Cost": "5435"
    }]
}

Below is the code with items not mapped properly:


import React, { useState, useEffect } from 'react';
import { Formik, Field, FieldArray } from "formik";
import axios from 'axios';

const App: React.FC = () => {

    const [initialValues, setInitialValues] = useState();

    async function getInitialValues() {
        try {

             return await axios({
                method: "GET",
                url: "http://localhost:53132/api/Projects/1",
            })
                .then((response: any) => {

                //console.log(response);

                const initialValues = {
                    Costs: response.data.costs
                }

                console.log(initialValues);

                return initialValues;

            })
            .catch((error: any) => {
                console.log(error);
            });

        } catch (error) {
            console.error(error);
        }
    }

    useEffect(() => {
        getInitialValues().then(res => setInitialValues(res));

        return () => {
            //console.log(initialValues);
        };

    }, []);

    const handleOnSubmit = (values: any, actions: { setSubmitting: (arg0: boolean) => void; resetForm: () => void; }) => {
        console.log(values)
    };

    return initialValues ? (

            <Formik initialValues={initialValues}
                    onSubmit={handleOnSubmit}>

                    {props => (

                        <form onSubmit={props.handleSubmit}>

                            <FieldArray

                                {...props.values.costs.map((method: { name: any}, index: any) => (

                                    <div key={index}>
                                        <input
                                            name={`costs.${index}.item`}
                                            value={method.name}
                                            onChange={props.handleChange}
                                        />

                                    </div>

                                ))}

                            />

                            <button type="submit">Submit</button>
                        </form>
                    )}

            </Formik>

    ) : <span>loading...</span>;

}

export default App;
2
  • In the API response handler, you have Costs: response.data.costs instead of costs: response.data.costs. (Notice the capital C). Is that just a typo in the question, or in your actual code? Commented Feb 3, 2020 at 18:38
  • I replaced the code to use costs: response.data.costs. The error is gone, but the field does not render. Commented Feb 3, 2020 at 18:49

1 Answer 1

2

You should use name and render props for the FieldArray component. You also had a typo while setting Costs instead of costs.

const renderFieldArray = (props: FormikProps<any>) => (arrayHelpers: any) => {
  return props.values.costs.map((x, index) => {
    return (
      <div key={index}>
        <input
          name={`costs.${index}.item`}
          value={method.name}
          onChange={props.handleChange}
        />
      </div>
    );
  });
};

<FieldArray name="costs" render={renderFieldArray(props)} />
Sign up to request clarification or add additional context in comments.

8 Comments

Thank you for the example snippet. I get this error when using the snippet: "Expected an assignment or function call and instead saw an expression @typescript-eslint/no-unused-expressions".
@TerryDoll, you might need to remove the arrayHelpers variable if you're not using it.
I added: "arrayHelpers: any", but I am getting this error: "Cannot find name 'props'." I suspect that is because the initialValues are async?
@TerryDoll, I updated the answer to pass the props.
Thanks for the revised code. I tried it, but getting the following error: "Parameter 'props' implicitly has an 'any' type."
|

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.