Reputation: 61
I'm learning Javascript, so pardon any mistakes in how I phrase the question.
I am writing a chess program to practice and learn. Currently, I am trying to write a function to find the color of a piece with the position as the parameter. The relevant pieces of code are as follows. The first two work as they were designed to, but the last does not.
let allPieces = board.getElementsByClassName('piece');
This sets allPieces
as an object with the key values the html elemnts representing each piece, both black and white.
const getPiecePosition = function(element) {
let position = window.getComputedStyle(element).getPropertyValue('grid-row-start');
let letterIndex = alphabet.findIndex(function(letter) {
return letter === position[0];
});
letterIndex += 1;
return [letterIndex, Number(position[1])];
}
This takes a parameter in the form of the allPieces
object with a specific key and returns the position as an array with the column number first and the row number second. ex. [2,3]
.
const getPieceByPosition = function(position) {
let pce = Object.keys(allPieces).forEach(function(piece) {
if (getPiecePosition(allPieces[piece]) == position) {
return allPieces[piece].borderColor;
}
})
return pce;
}
This is the function I am having trouble with. The idea behind it is that it will take each key in the allPieces
object and loop through them using forEach()
into the getPiecePosition()
function to compare it with the position entered as the parameter. Since only one piece can inhabit any tile at once, it should never return multiple values.
I honestly don't know where to start debugging this code, but I have been trying for about an hour. It always just returns undefined
instead of a truthy value of any kind.
Upvotes: 1
Views: 96
Reputation: 50749
Your last function has a few issues:
getPiecePosition(allPieces[piece]) == position
Assuming position
is an array, you're trying to compare an array with an array here using ==
. However, since the two arrays are different references in memory, this will always give false
, even if they contain the same elements:
console.log([2, 3] == [2, 3]); // false
You're trying to return
from the callback of .forEach()
. This won't achieve what you want, as return
will jump out of the .forEach
callback function, not your outer getPieceByPosition()
function. This leads me to your final issue:
The .forEach()
method doesn't return anything. That is, it doesn't evaluate to a value once it is called. This means that let pce
will always be undefined
since you're trying to set it to the return value of .forEach()
. This, in contrast to let letterIndex
, is different, as letterIndex
is set to the return value of .findIndex()
, which does have a return value and is determined by the function you pass it.
One additional thing you can fix up is the use of Object.keys(allPieces)
. While this works, it's not the best approach for looping over your elements. Ideally, you would be able to do allPieces.forEach()
to loop over all your elements. However, since allPieces is a HTMLCollection, you won't be able to do that. Instead, you can use a regular for loop or a for..of
loop to loop over the values in your HTMLCollection.
Alternatively, there is a way to make allPieces.forEach()
work.
Instead of using board.getElementsByClassName('piece');
, you can use the method .querySelectorAll('.piece')
, which will give you a NodeList. Unlike a HTMLCollection, a NodeList allows you to use .forEach()
on it to loop through its elements.
Upvotes: 1
Reputation: 1003
The return type of getElementsByClassName
HTMLCollection Object. You should't use Object.keys
to loop through each of 'piece' element. Insted, use the follow.
for(var i = 0 ; i < allPieces.length ; i++){
var piece = allPieces[i];
... // and, do whatever with the getPiecePosition(piece)
}
Upvotes: 0