Home > Software engineering >  Uncaught TypeError: data[index] is undefined | Set input value in React
Uncaught TypeError: data[index] is undefined | Set input value in React

Time:01-10

I wrote the below code which displays each item with {t.title}

When I click on each checkbox item, plant_id: t.plant_id is correctly stored in setPlantsFill

But when I try to enter input value, for example, the third value of data[index]["effectiveness"] = e.target.value;, an error is shown to me: Uncaught TypeError: data[index] is undefined But if I enter in order, there is no problem

How can I solve this problem?

I want the final output for each item to be as (for example we have 3 item in allPlants): { "plant_id": 2, "effectiveness": 100 }, { "plant_id": 24, "effectiveness": 80 }, { "plant_id": 13, "effectiveness": 15 }

this is my code:

const [allPlants, setAllPlants] = useState([]);

const [plantsFill, setPlantsFill] = useState([]);

{allPlants.map((t, index) => {
              return (
                <div className="form-row mb-2" key={index}>
                  <div className="col-md-2">
                    <div className="form-check">
                      <input
                        type="checkbox"
                        className="form-check-input"
                        onChange={(e) => {
                          if (e.target.checked) {
                            setPlantsFill([
                              ...plantsFill,
                              {
                                plant_id: t.plant_id,
                              },
                            ]);
                          } else {
                            // remove from list
                            setPlantsFill(
                              plantsFill.filter(
                                (pItem) => pItem.plant_id !== t.plant_id
                              )
                            );
                          }
                        }}
                        value={plantsFill}
                      />

                      <label className="form-check-label">{t.title}</label>
                    </div>
                  </div>

                  <div className="col-md-1">
              
                    <input
                      type="text"
                      className="form-control"
                      onChange={(e) => {
                        let data = [...plantsFill];
                        data[index]["effectiveness"] = e.target.value;
                        setPlantsFill(data);
                      }}
                    />
                  </div>
                </div>
              );
            })}



CodePudding user response:

With the discussion I tried something and it works as I understand the problem :

const onCheckChange = (e, t) => {
    if (e.target.checked) {
      setPlantsFill([
        ...plantsFill,
        {
          plant_id: t.plant_id
        }
      ]);
    } else {
      // remove from list
      setPlantsFill(
        plantsFill.filter((pItem) => pItem.plant_id !== t.plant_id)
      );
    }
  };

  const onTextChange = (e, t) => {
    let data = [...plantsFill];
    const index = data.findIndex((d) => d.plant_id === t.plant_id);
    if (index > -1) {
      data[index].effectiveness = e.target.value;
    }
    setPlantsFill(data);
  };

  return (
    <div>
      {allPlants.map((t, index) => {
        return (
          <div className="form-row mb-2" key={index}>
            <div className="col-md-2">
              <div className="form-check">
                <input
                  type="checkbox"
                  className="form-check-input"
                  onChange={(e) => onCheckChange(e, t)}
                  value={!!plantsFill.find((p) => p.plant_id === t.plant_id)}
                />

                <label className="form-check-label">{t.title}</label>
              </div>
            </div>

            <div className="col-md-1">
              {!!plantsFill.find((p) => p.plant_id === t.plant_id) && (
                <input
                  type="text"
                  className="form-control"
                  onChange={(e) => onTextChange(e, t)}
                />
              )}
            </div>
          </div>
        );
      })}
    </div>
  );
  • Related