1

I'm currently building a webpage with the purpose to mirror a certain table in a MySQL server. This is what the page currently looks like.

enter image description here

For each row of the table, there are two buttons, and the red one should be able to delete the record from the server.

I've managed to use frontend JavaScript to pull the data from the server and build the table using "innerHTML" with this code:

async function loadData(){
    var result = await fetch("http://localhost:8080/dados",
        {
            method:"POST",
            headers:{'Content-Type': "application/json"},
            body:JSON.stringify({command: "fetch", codMovimento: 0})
        }
    )
    tableJson = await result.json()
    console.log(tableJson)

    var table = document.getElementById("minhaTabela");

    table.innerHTML += "<tbody>"
    table.innerHTML += `<thead class="thead-dark">
    <tr>
        <th scope="col">Código</th>
        <th scope="col">Tipo de Movimento</th>
        <th scope="col">Técnico</th>
        <th scope="col" style="width:350px;">Peça</th>
        <th scope="col">Código da Peça</th>
        <th scope="col">Origem</th>
        <th scope="col">Destino</th>
        <th scope="col" style="text-align: center;">Quantidade</th>
        <th scope="col"></th>
        <th scope="col"></th>
    </tr>
    </thead>`

    for(var i=0; i < tableJson.length; i++){
        table.innerHTML +=
        `
        <tr>
            <th scope="row">${tableJson[i].CodMovimento}</th>
            <td>${tableJson[i].TipoMovimento}</td>
            <td>${tableJson[i].Tecnico}</td>
            <td>${tableJson[i].NomePeca}</td>
            <td>${tableJson[i].CodPeca}</td>
            <td>${tableJson[i].Origem}</td>
            <td>${tableJson[i].Destino}</td>
            <td style="text-align: center;">1</td>
            <td>
                <button type="button" class="btn btn-success" id="approveButton${i}">
                <img src="/assets/check.svg" alt="Bootstrap" width="32" height="32">
                </button>
            </td>
            <td>
                <button type="button" class="btn btn-danger" id="refuseButton${i}">
                <img src="/assets/x.svg" alt="Bootstrap" width="32" height="32">
                </button>
            </td>
        </tr>
        `
    }

    table.innerHTML += "</tbody>"

    declareButtons(tableJson)

}

loadData()

Now, I'm trying to define the onClick function for the red button, using this code:

async function declareButtons(tableJson){
    const approveButtons = []
    const refuseButtons = []
    
    for(var i=0; i < tableJson.length; i++){
    
        approveButtons.push(document.getElementById(`approveButton${i}`));
        approveButtons[i].onclick = async function(){
            console.log("Teste234")
        }
    
        refuseButtons.push(document.getElementById(`refuseButton${i}`));
        refuseButtons[i].onclick = async function(tableJson){

            console.log(tableJson[i].CodMovimento)
            var result = await fetch("http://localhost:8080/dados",
                {
                    method:"POST",
                    headers:{'Content-Type': "application/json"},
                    body:JSON.stringify({command: "delete", codMovimento: tableJson[i].CodMovimento})
                }
            )

            location.reload()

        }
        
    }
}

However, when pressing one of the red buttons, I get the following error:

enter image description here

I've tried using try/catch blocks inside the onClick function, which makes the error stop appearing, but then the button still does not work as expected (the code to delete the record is not executed).

Does anybody know how I could implement this?

Thanks in advance

7
  • In the for loop, use let i = 0 instead of var i = 0. That will deal with the loop variable problem, though there may be other bugs to fix. Commented Aug 17, 2022 at 13:01
  • @Pointy thanks for the reply. I did that, but I'm still getting the same error unfortunately. Commented Aug 17, 2022 at 13:21
  • 1
    Well the issue with using var instead of let is that all of the event handlers will share the same variable i. When the initialization loop finishes, the value of i will be beyond the end of the array, and that's where the error comes from. With let, there is a separate i for each iteration. You can add console.log(i) before the current console.log() you already have to verify that i is correct. Commented Aug 17, 2022 at 13:27
  • You might want to show your backend code that actually deletes the record from the DB. Your fetch sends a command: delete key/value to some backend API, but how does that work? Perhaps the problem is there? Commented Aug 17, 2022 at 13:31
  • @cssyphus the error is rising from the line "console.log(tableJson[i].CodMovimento)", right before calling the fetch function. Even if I delete the fetch part, the error persists, so the problem is not coming from the backend. Commented Aug 17, 2022 at 13:38

2 Answers 2

2

You've accidentally masked the tableJson data you want with a different object.

async function declareButtons(tableJson){
// ....
    console.log(tableJson) // this will be the table JSON object
    refuseButtons[i].onclick = async function(tableJson){
        console.log(tableJson) // this will be the click event

onclick handlers receive an event object. In declareButtons tableJson will contain whatever you passed to declareButtons... but inside that onclick handler, tableJson now refers to the click event object instead.

You could use a different name for the event object in the function definition, or just remove it altogether:

async function declareButtons(tableJson){
// ....
    refuseButtons[i].onclick = async function(e){
        console.log(tableJson) // this will be the original tableJson
        console.log(e) // the click event object
Sign up to request clarification or add additional context in comments.

Comments

1

I managed to solve it by declaring the variable containing the table information as a global variable, instead of local (var tableJson)

1 Comment

That'll work, but you'll likely regret it later. Best to avoid polluting global

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.