Search code examples
javascripthtmltextinput

HTML text input value null when it shouldn't be


I have an HTML website where I set up dynamically created text input field, all with the IDs root a (where a is the row number).

<input type="text" id="root'+ a +'" class="inlet1" >

So these things are generated in a for loop.

So I want to send back the data from the selected text inputs to the backend, which works fine for other types of elements but not with the text inputs.

Here's my JavaScript code:

window.addEventListener("DOMContentLoaded", (event) => {
  var gomb = document.getElementById("submit");

  gomb.addEventListener("click", async function () {
    let len = document.querySelectorAll(".id");

    console.log(len);

    for (let i = 1; i <= len.length; i++) {
      var rowroot = document.getElementById("root" + i).value;
      var rowaction = document.getElementById("action" + i).value;

      var rowmat = document.getElementById("material" + i);
      var rowcdate = document.getElementById("cdate" + i);
      var rowmatnum = document.getElementById("materialnum" + i);
      var rowsloc = document.getElementById("sloc" + i);
      var rowbatch = document.getElementById("batch" + i);
      var rowrsn = document.getElementById("rsn" + i);
      var rowmvt = document.getElementById("mvt" + i);
      var rowrespodep = document.getElementById("respo" + i);
      var rowdocheader = document.getElementById("docht" + i);
      var rowqty = document.getElementById("qty" + i);
      var rowscrapval = document.getElementById("valueincl" + i);
      var rowcostc = document.getElementById("costcenter" + i);

      var rowrespo = document.getElementById("resp" + i).value;
      var rowdeadline = document.getElementById("deadline" + i);
      var rowstatus = document.getElementById("status" + i);
      console.log(rowroot);
      await fetch("/process", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          id: i,
          material: rowmat.innerText,
          cdate: rowcdate.innerText,
          materialnum: rowmatnum.innerText,
          sloc: rowsloc.innerText,
          batch: rowbatch.innerText,
          mvt: rowmvt.innerText,
          reason: rowrsn.innerText,
          responsibledep: rowrespodep.innerText,
          docheadtext: rowdocheader.innerText,
          quantity: rowqty.innerText,
          scrapval: rowscrapval.innerText,
          costcenter: rowcostc.innerText,
          rootcause: rowroot,
          action: rowaction,
          responsible: rowrespo,
          status: rowstatus.innerText,
        }),
      })
        .then((response) => response.json())
        .then((data) => {
          // Handle the response from the backend
        })
        .catch((error) => {
          console.error("Error:", error);
        });
    }
  });
});

And Here's the error, I'm getting:

Uncaught (in promise) TypeError: Cannot read properties of null (reading 'value')
    at HTMLButtonElement.<anonymous> ((index):250:60)
(anonymous) @ (index):250

I tried waiting for the DOM content to load and adding defer to the script element tags, but none of them worked.


Solution

  • Your Input component is an invalid HTML as well as an invalid JavaScript.

    <input type="text" id="root'+ a +'" class="inlet1" />
    

    This piece of code will make the input ID like this:

    root'+ a +' // as a string
    

    Since this is HTML, not JSX, you can't pass JavaScript code directly into the HTML elements attributes. In JSX, you could do it like so:

    <input type="text" id={"root" + a} class="inlet1" />
    

    But since you're using HTML, you have to assign the dynamic ID attribute using your JavaScript.

    Here's an example:

    var inputs = document.querySelectorAll('input')
    inputs.forEach((input, i)=> {
      input.id = "root" + i
    })
    

    Basically, looping over all the input fields, and assigning them ID attributes sequentially.