Search code examples
javascriptfunctiondomeventsundefined

JavaScript function returning undefined. Looping through nodelist of buttons for click event


While trying to adapt my console.log Rock Paper Scissors game to use a GUI - I've setup buttons for the user input but the function I've put together keeps returning undefined (getPlayerSelection).

Specifically I'm trying to return the text content of the button clicked so that I can use that as the user's input. The console.log(input) shows the correct string but when I try to return that value it always shows as undefined.

HTML

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Rock Paper Scissors!</title>
</head>
<body>

    <section id="choices">
    <button class="button">Rock!</button>
    <button class="button">Paper!</button>
    <button class="button">Scissors!</button>
    </section>

    <script src="javascript.js" defer></script>
</body>

JAVASCRIPT

    // player input

function getPlayerSelection(){

        const buttons = document.getElementsByClassName('button');

        let input = '';
            
        for (const btn of buttons) {
            btn.addEventListener('click', () => {
                input =  btn.textContent;
                console.log(input);
            })
        }

        return input;
    
    }


    // computer input

function getComputerChoice(){
        let randomChoice = Math.floor(Math.random() * 3);
            
        if(randomChoice === 0){
            return("Rock!")
        } else if(randomChoice === 1){
            return("Paper!")
        } else {
            return("Scissors!")
        }
    }


function playRound(playerSelection, computerSelection) {

    playerSelection = getPlayerSelection();
    computerSelection = getComputerChoice();

I've tried setting up individual class names for each button and having their own event listeners but I think I must be misunderstanding how DOM manipulation works. This also returns undefined.

    const rockBtn = document.querySelector('.rockButton');
    rockBtn.addEventListener('click', () => {
        return 'Rock!';
    });

    const paperBtn = document.querySelector('.paperButton');
    paperBtn.addEventListener('click', () => {
        return 'Paper!';
    });

    const scissorsBtn = document.querySelector('.scissorsButton');
    scissorsBtn.addEventListener('click', () => {
        return 'Scissors!';
    });


Solution

  • The problem with your code is that your higher order function, playGround, was not structured well and you tried returning the text content of the buttons before hooking into them via the DOM API.

    There was no error logged because you initialized the input variable with an empty string and thus an empty string was all that was returned.

    To cut the long story short, whenever you called the playGround function, the empty input variable was returned, you called the function before linking the buttons in your code.

    The following code should work, you can tweak it as you see fit

    HTML

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>Rock Paper Scissors!</title>
        <script src="javascript.js" defer></script>
      </head>
      <body>
        <section id="choices">
          <button class="button">Rock!</button>
          <button class="button">Paper!</button>
          <button class="button">Scissors!</button>
        </section>
      </body>
    </html>
    

    JS

    const buttons = document.getElementsByClassName("button");
    for (const btn of buttons) {
      btn.addEventListener("click", () => {
        playRound(btn.textContent);
      });
    }
    
    function getPlayerSelection(input) {
      return input;
    }
    
    function getComputerChoice() {
      let randomChoice = Math.floor(Math.random() * 3);
    
      if (randomChoice === 0) {
        return "Rock!";
      } else if (randomChoice === 1) {
        return "Paper!";
      } else {
        return "Scissors!";
      }
    }
    
    function playRound(playerSelection) {
      playerSelection = getPlayerSelection(playerSelection);
      computerSelection = getComputerChoice();
      console.log(`Player: ${playerSelection}`, `Computer: ${computerSelection}`);
    }