Passing properties object (with onclick function using this.id) to HTML element constructor function

I’m creating an HTML button with JS and I’m defining the onclick function using a element constructing function I wrote/copied from Marijn Haverbeke’s Eloquent Javascript

I am creating a button that needs to pass this.id to the onclick function. The onclick function runs, but this.id is coming through in packItem() as undefined.

This method of creating buttons has been working great for me but I can’t get the this.id to come through into packItem().

Run code snippet to obtain the undefined id:

let element = elt(
  "button", {
    id: "test_id",
    onclick: () => packItem(this.id),
  },
  "packed"
)

document.body.appendChild(element);

function packItem(id) {
  console.log("packing item:", id);
}


function elt(type, props, ...children) {
  let element = document.createElement(type);
  if (props) Object.assign(element, props);
  for (let child of children) {
    // console.log(typeof child);
    if (typeof child != "string") element.appendChild(child);
    else element.appendChild(document.createTextNode(child));
  }
  return element;
}

I assumed the problem lies in how this.id is getting transferred through the prop object being added to the element in elt() but can’t figure out why exactly and then I tried adding the onclick after my elt function, which ruled out my incorrect assumption above. What am I doing wrong!?

 let thisbutton = elt(
    "button",
    {
      id: `${customer_id}/${value.id}`,
      // onclick: () => packItem(this.id),
    },
    "packed"
  );
  thisbutton.onclick = () => packItem(this.id);

doesn’t work either….

I realize that I am not passing anything to packItem() when I write as () => packItem(this.id) but onclick: (this.id) => packItem(this.id) returns: Uncaught SyntaxError: Invalid destructuring assignment target and I’ve tried simply defining onclick this way: onclick: packItem(this.id) but then packItem() doesn’t even run.

Answer

Please change arrow function to the normal function.

let element = elt(
  "button", {
    id: "test_id",
    onclick: function(){packItem(this.id)},
  },
  "packed"
)

document.body.appendChild(element);

function packItem(id) {
  console.log("packing item:", id);
}


function elt(type, props, ...children) {
  let element = document.createElement(type);
  if (props) Object.assign(element, props);
  for (let child of children) {
    // console.log(typeof child);
    if (typeof child != "string") element.appendChild(child);
    else element.appendChild(document.createTextNode(child));
  }
  return element;
}

Leave a Reply

Your email address will not be published. Required fields are marked *