Tuesday 19 July 2022

Spot The Bug: Pushing it with JavaScript

What's up, programmers?!

It's time for Spot The Bug once again, and JavaScript is the language of the day.

Meet your doom, bugs!

I was trying to make a simple soccer team builder using HTML, CSS and JavaScript. The HTML and CSS were fine, but where I inevitably screwed up was the JavaScript. This may be an important lesson for fledgling programmers, so listen up!

This was the code...
<!DOCTYPE html>
<html>
    <head>
        <title>Team Builder</title>

        <style>
            label
            {
                width: 5em;
                display: inline-block;
            }
        </style>

        <script>
            var players =
            [
                { "name": "Name", "position": "Position"}
            ];

            function addPlayer()
            {
                var name = document.getElementById("txtName").value;
                var pos = document.getElementById("ddlPos").value;

                if (newPlayers.length == 0) {
                    newPlayers = players.push({ "name": name, "position": pos});
                }
                    
                var content = "";

                for (var i = 0; i < newPlayers.length; i++)
                {
                    content += "<tr><td>" + newPlayers[i].name + "</td><td>" + newPlayers[i].position + "</td></tr>";
                }

                document.getElementById("newPlayers").innerHTML = content;
            }

            let newPlayers = [];
        </script>
    </head>

    <body>
        <label>Name:</label> <input id="txtName" />
        <br />
        <label>Position:</label>
        <select id="ddlPos">
            <option value="Defence">Defence</option>
            <option value="Midfield">Midfield</option>
            <option value="Forward">Forward</option>
        </select>
        <br />
        <button onclick="addPlayer()">Add Player</button>

        <hr />

        <table id="newPlayers">

        </table>
    </body>
</html>


The point was, nothing would be displayed in the newPlayers div if I entered nothing. But once I started entering stuff, there should be headings and the data that I entered.

What went wrong

All I ever got, no matter how many times I entered data, was this.



Looking at the console gave me this. So the value of newPlayers was an integer and not an array?!




Why it went wrong

This is a bit of a rookie error. I was under the impression that setting newPlayers this way would give newPlayers the value of players after the input was pushed to players.

newPlayers = players.push({ "name": name, "position": pos});


However, the push() method returns not the resultant array, but the length of the resultant array! Here's the specification for the push() method.

No wonder I couldn't apply a For loop to iterate through newPlayers, because newPlayers would be an integer!

How I fixed it

First, I should have made a copy of players using the slice() method.
if (newPlayers.length == 0) {
  newPlayers = players.slice();
}

var content = "";


Then I should have pushed the input.
if (newPlayers.length == 0) {
  newPlayers = players.slice();
}

newPlayers.push({ "name": name, "position": pos});

var content = "";


And now it worked!




Moral of the story

As always, when using any method or function, it is important to understand what the method returns, rather than what you think it returns.

Don't push() your luck,
T___T

No comments:

Post a Comment