Home > other >  How to pass Object as parameter to a function onclick
How to pass Object as parameter to a function onclick

Time:12-22

I am facing some issues while trying to pass JSON object as a parameter to function! but on that function, while consoling log the data I am getting [object:object].

Here is my code:

function buildTable(data) {
  var table = document.getElementById("myTable");
  table.innerHTML = "";
  for (var i = 0; i < data.length; i  ) {
    var row = `<tr > <td>${data[i].name}</td> <td>${data[i].audio_muted}</td> <td>${data[i].video_muted}</td> <td><button id="audio_handle"  onclick="handleMembers('${data[i]}')">Video</button></td>`;

    table.innerHTML  = row;
  }
}

function handleMembers(data) {
  console.log("data = >", data); //= [object:object]
}

The issue is when I am calling handle function from the button inside template literal string I m getting [object:object] as output

Where I am going wrong?

CodePudding user response:

I think it's the wrong approach to do that. You should try to create the element using the DOM api and add the eventListener to the selected element, something like:

function buildTable(data) {
 const table = document.getElementById("myTable");

 for(let d of data) {
    const tr = document.createElement("tr");      
    const td1 = document.createElement("td");
    td1.textContent = d.name;       
    
    const td2 = document.createElement("td");
    td2.textContext = d.audio_muted;
    
    const td3 = document.createElement("td");
    td3.textContent = d.video_muted;
    
    const tdButton = document.createElement("button");
    tdButton.classList.add("btn", "btn-primary");
    tdButton.addEventListener("click", () => handleMembers(d));
    
    tr.appendChild(td1)
    tr.appendChild(td2)
    tr.appendChild(td3)
    tr.appendChild(tdButton);
    
    table.appendChild(tr)

 }
}

CodePudding user response:

I fixed a few points in the following snippet and added some HTML and some sample data:

// some sample data for illustration:
const data=[{id:1,name:"Harry",audio_muted:1,video_muted:1},{id:2,name:"Ron",audio_muted:1,video_muted:0},{id:3,name:"Hermiony",audio_muted:0,video_muted:1},{id:4,name:"Ginny",audio_muted:0,video_muted:1}];

const tbl=document.getElementById("myTable");
tbl.innerHTML = data.map((itm,i)=>`<tr > <td>${itm.name}</td> <td>${itm.audio_muted}</td> <td>${itm.video_muted}</td> <td><button data-id="${i}" >Video</button></td>`).join("\n")

tbl.addEventListener("click",ev=>{
  if (ev.target.tagName==="BUTTON")
    console.log("data = >", data[ev.target.dataset.id]) ; //= [object:object]
})
<table id="myTable"></table>

As @Quentin already mentioned you should not include JavaScript code within a template string. This gets too complicated to read and to maintain. Instead I used a delegated event-handler on the table itself to listen for the click on the button elements. By doing all this there was no need anymore for the two named functions.

Another thing that comes to my mind is: Never use element.innerHTML = ... inside a for loop as this will potentially become really slow. It is generally better to assemble the whole HTML string in one go and then assign it to the innerHTML property.

  • Related