0

I have verified that at some point the first if condition is true. Shouldn't the function return true and stop executing? However; in this case even after the first if condition is true the function keeps on executing until the forEach loop is finished and then exits returning false every time. Can someone tell me where the error is?

function checkValid(id){
    pressedButtons.forEach(button => {
        console.log(`ID: ${id} and Button: ${button}`)
        if (id == button+1 || id == button+8 || id == button-1 || id == button-8){
            console.log("IM HERE")
            return true
        }
    })
    return false
}
Hassaan Hasan
  • 341
  • 3
  • 12
  • Returning inside the callback doesn't make the outer function return. – Andrew Li Apr 06 '17 at 16:22
  • 1
    use [`Array.prototype.some`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some), which *will* short-circuit on truthy values (of course, you'd still have to *return* that resultant value). – zzzzBov Apr 06 '17 at 16:24
  • 1
    the `.forEach(button => {})` bit creates a function. You're returning from that function, not the checkValid. Create a variable in your checkValid function which can be set to true in the forEach, and returned at the end. – Hodrobond Apr 06 '17 at 16:24
  • Thanks guys. I get it now. – Hassaan Hasan Apr 06 '17 at 16:26
  • Possible duplicate of [how to stop Javascript forEach?](http://stackoverflow.com/questions/6260756/how-to-stop-javascript-foreach) – Nelson Teixeira Apr 06 '17 at 16:27

2 Answers2

0

The issue appears to be function scoping/closures

I've added an "isValid" variable which will maintain the "validity" throughout the forEach functions. button => {} is a function with it's own scope which gets run on each of the pressedButtons. return true only returned from the scoped function, not the checkValid function.

function checkValid(id){
    var isValid = false;
    pressedButtons.forEach(button => {
        console.log(`ID: ${id} and Button: ${button}`)
        if (id == button+1 || id == button+8 || id == button-1 || id == button-8){
            console.log("IM HERE")
            isValid = true;
        }
    })
    return isValid;
}
Hodrobond
  • 1,665
  • 17
  • 18
  • but this will not break the loop. It will still continue at the end of array then will return validation. – serdar.sanri Apr 06 '17 at 16:30
  • It isn't a loop so much as individual functions run on each element. [There isn't a built-in break for forEach](http://stackoverflow.com/questions/2641347/how-to-short-circuit-array-foreach-like-calling-break) – Hodrobond Apr 06 '17 at 16:32
  • Can you please elaborate on what you're trying to accomplish? Some more context might allow me to help a little more =) – Hodrobond Apr 06 '17 at 16:35
0

You can use Promises on this to stop proceeding foreach loop.

function checkValid(id){
   var promises= [];
   pressedButtons.forEach(button => {
    return new Promise(function(resolve, reject){
      console.log(`ID: ${id} and Button: ${button}`)
       if (id == button+1 || id == button+8 || id == button-1 || id == button-8){
        console.log("IM HERE")
        resolve(true);
      }
    });
  });
  Promise.race(promises).then(function(result){
    // as soon as any promise resolves it will fall here
  });

}

serdar.sanri
  • 2,217
  • 1
  • 17
  • 21