I am attempting to have a "flashcard" show no background color when it is unanswered, green when it is correctly answered, and yellow when it is incorrectly answered. The properties for each card are stored in a nested object. I am having issues using conditional rendering to properly show my content.
Code: Here is what I want to accomplish, but the JSX conditional statement is only registering the last statement in the className.
<div className="row">
{Object.keys(this.state.selections).map( (lang, index) => (
<>
{Object.keys(this.state.selections[lang]).map( (cat, index) => (
<>
{Object.keys(this.state.selections[lang][cat]).map( (sect, index)=> (
<>
{Object.keys(this.state.selections[lang][cat][sect]).map( (letter, index)=> (
<>
{this.state.selections[lang][cat][sect][letter].show &&
<div className={
(this.state.selections[lang][cat][sect][letter].correct ? correct: unanswered),
(this.state.selections[lang][cat][sect][letter].incorrect ? incorrect : unanswered)
} key= {index}>
</div>
}
</>
))}
</>
))}
</>
))}
</>
))}
</div>
Essentially, I want to place a conditional statement in the className to change the background based off the object property values being true/false.
Obj model:
{
"Hiragana": {
"Main Kana": {
"Vowels": {
"a": {
"characterName": "A",
"character": "あ",
"unicode": "\u0026#12354;",
"hexEncoding": "\u0026#x3042",
"englishTranslation": "a",
"alternateEnglishTranslation": "",
"isLetter": "1",
"alphabet": "hir",
"show": false,
"answer": "",
"correct": false,
"incorrect": false,
"unanswered": true
},
Bonus question: Having to loop through each object layer seems a bit messy and tedious... Would there be any good way to shorten this up? The lang and cat are selected by input so they cannot be hard-coded. While my current solution "works" I want to improve myself when possible.
Update: Working code from the solution offered by @CertainPerformance
<div className="row">
{Object.keys(this.state.selections).map(lang =>
Object.values(this.state.selections).map( (cat) =>
Object.values(cat).map((sect, indexCat) =>
Object.values(sect).map((sectLetters, indexSect) =>
Object.values(sectLetters).map((letter, indexSectL) =>
letter.show &&
<div
className={getBgClass(letter)}
key={indexSectL}>
<div>
<h5 className="card-title" >{letter.character}</h5>
<input data-lang={lang} data-cat={Object.getOwnPropertyNames(cat)[indexCat]} data-sect={Object.getOwnPropertyNames(sect)[indexSect]} type="text" name={letter.characterName} value={letter.answer} onChange={this.handleChange.bind(this)} />
</div>
</div>
)
)
)
)
)}
</div>
For those confused by my explanation of accessing the array generated by Object.values, here is an example with simple console.log to better explain.
Object.values(this.state.selections).map((cat) =>{
Object.values(cat).map((sect, indexCat) => {
console.log("Cat: ", Object.getOwnPropertyNames(cat)[indexCat]);
});
});