skip to Main Content

I’m writing simple rock-paper-scissors game. In this piece of code I’m trying to assign id value of the clicked img to a variable using .forEach method. It just doesn’t work. If statements does work but somehow string doesn’t add to a variable.

const weapons = document.querySelectorAll("img");
let playerWeapon = "";

weapons.forEach((weapon) => {
  weapon.addEventListener("click", (event) => {
    if (weapon.id == "paper") {
      playerWeapon += "paper";
    } else if (weapon.id == "scissors") {
      playerWeapon += "scissors";
    } else if (weapon.id == "rock") {
      playerWeapon += "rock";
    }
  });
});
console.log(playerWeapon);

I’ve replaced concatenation with console.log to see if it returns value and it does return them. Tried adding return before concatenation, didn’t help.

2

Answers


  1. The problem is that you are immediately logging the value of playerWeapon, which means that the logged value will be "" since the user doesn’t have time to click on any of the images before the value is logged.

    Maybe something you could do is add an extra button that would log playerWeapon when clicked.

    Login or Signup to reply.
  2. You are facing the difference between synchronous and asynchronous code.
    Javascript usually executes the code synchronously, which means the JS interpreter executes immediately one line at a time from top to bottom.
    But you are using a callback function as well, which will be executed asynchron(at a later time) – when a user clicks on a weapon.

    Lets have a closer look into your code:

    weapons.forEach((weapon) => {
      // this line of code gets executed synchronously
      weapon.addEventListener("click", (event) => {
        // this is your callback function
        // this block scope executes asynchron
        if (weapon.id == "paper") {
          playerWeapon += "paper";
        } else if (weapon.id == "scissors") {
          playerWeapon += "scissors";
        } else if (weapon.id == "rock") {
          playerWeapon += "rock";
        }
        // asynchronous code end
      });
    });
    

    The second argument of addEventlistener is a callback function. A callback function is a javascript function, which is passed as parameter into another function. You have to be aware that this function is just defined but not executed yet!
    This function will be executed internally.

    So when you run your code, than your console.log(playerWeapon) will be executed before the code in your callback function. Thats the reason for getting just an empty string in your console output.
    What you can do instead of use console.log is adding an HTML Element which shows your clicked weapon or just use console.log e.g

    // add an html element to your page for showing your selected weapon
    const weaponHTML = document.getElementById('selected-weapon');
    const weapons = document.querySelectorAll("img");
    
    weapons.forEach((weapon) => {
      weapon.addEventListener("click", (event) => {
        // every time you click a weapon the id of the img element will be set as text into your new selected-weapon element
        weaponHTML.innerText = weapon.id
        // or you can do this instead
        console.log(weapon.id)
      });
    });
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search