0

My Array:

     var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];

Set Function to Button:

var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];

for (var idx = 0; idx < alphabet.length; idx++) {
  var bttn = document.createElement("button");
  bttn.innerText = alphabet[idx];
  bttn.onclick = function() {
    this.disabled = true;
    checkIfWordContainLetter(alphabet[idx]);
  }
  document.getElementById("hangmanContent").appendChild(bttn);
}

function checkIfWordContainLetter(letter) {
  alert(wordToGuess);
  alert(letter);
}

Causes undefined when I pass alphabet[idx] as parameter but if I pass for example 'a' it alerts a.

  • 2
    This Q&A should be closed. Please run my edit on your snippet and the error message should be enough to solve the issue yourself :) – Matías Fidemraizer Nov 20 '16 at 12:24
  • 1
    @MatíasFidemraizer: I don't believe that's the issue they're talking about. Clearly that element needs to exist, and hasn't been included in the example code, but the `undefined` will be displayed because of the *"function in a loop"* problem. –  Nov 20 '16 at 12:28
  • 1
    @squint Ah right, and this has been answered a lot of times. – Matías Fidemraizer Nov 20 '16 at 12:31

4 Answers4

1

Try below code:

var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
for(var idx=0;idx<alphabet.length;idx++)
  {
   var bttn = document.createElement("button");
   bttn.innerText = alphabet[idx];
   
   bttn.onclick = function () {this.disabled=true;
   
   checkIfWordContainLetter(this.innerText);
   }
   document.getElementById("hangmanContent").appendChild(bttn);
  }



function checkIfWordContainLetter(letter)
 {  
  alert(letter);
  alert(letter); 
  
 }
<body>
<div id="hangmanContent"></div>
</body>
Azeez Kallayi
  • 2,567
  • 1
  • 15
  • 19
1

This is a issue related to scopes.

When you click the button, idx is equal to 26, because the for already ended, this index doesn't exists on array.

You can simple correct this changing var idx to let idx, but note that this is implemented only on modern browsers.

A legacy solution could be:

for (var idx = 0; idx < alphabet.length; idx++) {
    var bttn = document.createElement("button");
    bttn.innerText = alphabet[idx];
    bttn.onclick = (function (index) {
        return function () {
            this.disabled = true;
            checkIfWordContainLetter(alphabet[index]);
        }
    } (idx));
    document.getElementById("hangmanContent").appendChild(bttn);
}

Read: JavaScript closure inside loops – simple practical example

Community
  • 1
  • 1
Edmundo Santos
  • 8,006
  • 3
  • 28
  • 38
1

Here is solution:

var alphabet = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'];
for(var idx=0;idx<alphabet.length;idx++)
{
        var bttn = document.createElement("button");
        bttn.innerText = alphabet[idx];
        bttn.onclick = function (idx)
        { 
           this.disabled=true;
           checkIfWordContainLetter(alphabet[idx]);
        }.bind(this, idx);
        document.getElementById("hangmanContent").appendChild(bttn);
}

function checkIfWordContainLetter(button)
{       
    //alert(wordToGuess);
    alert(button.innerText); 

}
Mihai Alexandru-Ionut
  • 47,092
  • 13
  • 101
  • 128
1

You should understand javaScript closure. When you clicked one of those buttons, the event handler will be excuted. You exposed the idx in the checkIfWordContainLetter(alphabet[idx]) to be 1,2,3,4,.....However, it will always be (alphabet.length + 1). They all refer to the same place in memory.

tomasran
  • 31
  • 5