Home > OS >  innerHTML pass in variable to function
innerHTML pass in variable to function

Time:02-25

I have a table which is pulling data from firebase:

r.insertCell(23).innerHTML = doc.data().username;
r.insertCell(24).innerHTML = doc.data().uid;
r.insertCell(25).innerHTML ='<button onclick="activateUserInTable(' doc.data().uid  ')">Activate User</button>';

I have a function:

function activateUserInTable(userId) {
  db.collection("users").doc(userId).update({
  activated: 1,
 });
}

I have a button in my table:

r.insertCell(25).innerHTML ='<button onclick="activateUserInTable(' doc.data().uid  ')">Activate User</button>';

Im trying to pass doc.data().uid into the button above in the table.

But this doesn't seem to work. This function does work if its outside the table and i manually pass in a uid. I want to be able to pass in the data from firebase into the function while the button is in the table.

CodePudding user response:

It's best to avoid setting event handlers via text assigned to onxyz attributes. It has several issues, not least that you have to create the text correctly (quotes are easily confused or mismatched), the browser has to parse it as code, and any functions you use have to be globals.

Instead, just use a function you create right then and there and attach it via addEventListener:

r.insertCell(23).innerHTML = doc.data().username;
r.insertCell(24).innerHTML = doc.data().uid;
const button = document.createElement("button");
button.type = "button";
button.addEventListener(
    "click",
    activateUserInTable.bind(null, doc.data().uid)
);
button.textContent = "Activate User";
r.insertCell(25).appendChild(button);

(I've used bind there so we're capturing the value of doc.data().uid as of when we create the function, not later when the function is called.)

That said, I think I'd avoid repeatedly calling doc.data(). Also, I'd avoid the XSS vulnerability that treating username as HTML might provide (and the same for uid, though I'm guessing it's a less likely vector) by treating them purely as text via textContent rather than innerHTML. Something like this:

const { username, uid } = doc.data();
r.insertCell(23).textContent = username;
r.insertCell(24).textContent = uid;
const button = document.createElement("button");
button.type = "button"; // I added this, it wasn't in your HTML, but note that
                        // the default `type` of `button` elements is
                        // `"submit"`. Only matters if this is in a `form`...
button.addEventListener("click", () => {
    activateUserInTable(uid);
});
button.textContent = "Activate User";
r.insertCell(25).appendChild(button);

(I don't need bind there and can use the easier to read [IMHO] arrow function because we've already captured the value of doc.data().uid to the uid constant.)

  • Related