Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to fix "TypeError: teachingExp.map is not a function", in React

I have 2 dynamic inputs academic and teaching exp but only academic works
and when I try to add a new field to teachingExp it returns typeError: teachingExp.map is not a
function
i have used the same code for both dynamic inputs but one works and other does not
both these input divs are inside a form

outside component return

const [academic, setAcademic] = useState([
    {
      degree: "",
      branch: "",
      university: "",
      completionYear: "",
      grade: "",
    },
  ]);

const [teachingExp, setTeachingExp] = useState([
    {
      university: "",
      designation: "",
      period: "",
    },
  ]);

const handleAcademicChange = (index, e) => {
    let data = [...academic];
    data[index][e.target.id] = e.target.value;
    setAcademic(data);
  };

const handleTeachingExpChange = (index, e) => {
    let data = [...teachingExp];
    data[index][e.target.name] = e.target.value;
    setTeachingExp(data);
  };

const addAcademic = () => {
    let newAcademic = {
      degree: "",
      branch: "",
      university: "",
      completionYear: "",
      grade: "",
    };
    setAcademic([...academic, newAcademic]);
  };

const addTeachingExp = () => {
    let newTeachingExp = {
      university: "",
      designation: "",
      period: "",
    };
    setTeachingExp(...teachingExp, newTeachingExp);
  };

const removeAcademic = (index) => {
    let data = [...academic];
    data.splice(index, 1);
    setAcademic(data);
  };

 const removeTeachingExp = (index) => {
    let data = [...teachingExp];
    data.splice(index, 1);
    setTeachingExp(data);
  };

inside return

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<div className="flex justify-center w-full m-auto my-6 p-4 font-sans ">
            <div className="flex flex-col p-3">
              <h3 className="text-center p-3 text-3xl font-medium text-gray-700 mb-5 ">
                Academic Qualifications
              </h3>
              {academic.map((input, index) => {
                return (
                  <div
                    key={index}
                    className="w-56 mb-4 relative group grid place-content-center place-items-center m-auto lg:grid-flow-col  gap-4 "
                  >
                    <div className="w-56 lg:w-40 p-2 xl:w-56">
                      <label className="text-sm font-light">Degree/Title</label>
                      <input
                        className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                        type="text"
                        required
                        id="degree"
                        autoComplete="true"
                        placeholder="Enter degree"
                        value={input.degree}
                        onChange={(e) => handleAcademicChange(index, e)}
                      />
                    </div>
                    <div className="w-56 lg:w-40 p-2 xl:w-56">
                      <label className="text-sm font-light">
                        Branch/Specialization
                      </label>
                      <input
                        className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                        type="text"
                        required
                        id="branch"
                        autoComplete="true"
                        placeholder="Enter branch"
                        value={input.branch}
                        onChange={(e) => handleAcademicChange(index, e)}
                      />
                    </div>

                    <div className="w-56 lg:w-40 p-2 xl:w-56">
                      <label className="text-sm font-light">
                        University/College
                      </label>
                      <input
                        className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                        type="text"
                        required
                        id="university"
                        autoComplete="true"
                        placeholder="Enter university"
                        value={input.university}
                        onChange={(e) => handleAcademicChange(index, e)}
                      />
                    </div>
                    <div className="w-56 lg:w-40 p-2 xl:w-56">
                      <label className="text-sm font-light">
                        Completion year
                      </label>
                      <input
                        className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                        type="text"
                        required
                        id="completedYear"
                        autoComplete="true"
                        placeholder="Enter completion year"
                        value={input.completedYear}
                        onChange={(e) => handleAcademicChange(index, e)}
                      />
                    </div>
                    <div className="w-56 lg:w-40 p-2 xl:w-56">
                      <label className="text-sm font-light">Grade/Marks</label>
                      <input
                        className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                        type="text"
                        required
                        id="grade"
                        autoComplete="true"
                        placeholder="Enter grade"
                        value={input.grade}
                        onChange={(e) => handleAcademicChange(index, e)}
                      />
                    </div>
                    {academic.length > 1 ? (
                      <TrashIcon
                        className="h-8 mt-5 mx-4 text-red-600"
                        onClick={() => removeAcademic(index)}
                      />
                    ) : (
                      ""
                    )}
                  </div>
                );
              })}

              <PlusCircleIcon
                className="h-12 p-2 mx-4 text-[#020493] mt-1"
                onClick={addAcademic}
              />
            </div>
          </div>


<div className="flex justify-center w-full m-auto my-6 p-4 font-sans ">
            <div className="flex flex-col p-3">
              <h3 className="text-center p-3 text-3xl font-medium text-gray-700 mb-5 ">
                Teaching Experience
              </h3>
              {teachingExp.map((input, index) => (
                <div
                  key={index}
                  className="w-56 mb-4 relative group grid place-content-center place-items-center m-auto lg:grid-flow-col  gap-4 "
                >
                  <div className="w-56 lg:w-40 p-2 xl:w-56">
                    <label className="text-sm font-light">
                      University/College
                    </label>
                    <input
                      className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                      type="text"
                      required
                      name="university"
                      autoComplete="true"
                      placeholder="Enter university"
                      value={input.university}
                      onChange={(e) => handleTeachingExpChange(index, e)}
                    />
                  </div>
                  <div className="w-56 lg:w-40 p-2 xl:w-56">
                    <label className="text-sm font-light">Designation</label>
                    <input
                      className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                      type="text"
                      required
                      name="designation"
                      autoComplete="true"
                      placeholder="Enter designation"
                      value={input.designation}
                      onChange={(e) => handleTeachingExpChange(index, e)}
                    />
                  </div>

                  <div className="w-56 lg:w-40 p-2 xl:w-56">
                    <label className="text-sm font-light">Period</label>
                    <input
                      className="form-control
        block
        w-full
        px-3
        py-1.5
        text-base
        font-normal
        text-gray-700
        bg-white bg-clip-padding
        border border-solid border-gray-300
        rounded
        transition
        ease-in-out
        m-0
        focus:text-gray-700 focus:bg-white focus:border-blue-600 focus:outline-none "
                      type="text"
                      required
                      name="period"
                      autoComplete="true"
                      placeholder="Enter period"
                      value={input.period}
                      onChange={(e) => handleTeachingExpChange(index, e)}
                    />
                  </div>
                  {teachingExp.length > 1 ? (
                    <TrashIcon
                      className="h-8 mt-5 mx-4 text-red-600"
                      onClick={() => removeTeachingExp(index)}
                    />
                  ) : (
                    ""
                  )}
                </div>
              ))}
              <PlusCircleIcon
                className="h-12 p-2 mx-4 text-[#020493] mt-1"
                onClick={addTeachingExp}
              />
            </div>
          </div>

>Solution :

You are not properly updating state when adding new. Rewrite to this:

  const addTeachingExp = () => {
    let newTeachingExp = {
      university: "",
      designation: "",
      period: "",
    };
    setTeachingExp([...teachingExp, newTeachingExp]); // HERE YOU FORGOT TO SPREAD IT INTO NEW ARRAY
  };
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading