I'm working on a browser quiz project. I have made an array of objects that has the question choices nested in a further object. I'm struggling to figure out how to compare the users choice of the 4 options to the correct answer in the answers array. I'm stuck because I don't know how to use for each on nested objects inside an array. I could use some advice or a better way to accomplish the same goal
const list = document.createElement('ol');
const li1 = document.createElement('li');
const li2 = document.createElement('li');
const li3 = document.createElement('li');
const li4 = document.createElement('li');
const choices = document.querySelector('.choices');
choices.appendChild(list);
list.appendChild(li1);
list.appendChild(li2);
list.appendChild(li3);
list.appendChild(li4);
const possibleAnswers = ['1', '2', '3', '4', '5', '6', '7'];
const questionPool = [
{
questionOne:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
},
{
questionTwo:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
},
{
questionThree:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
},
{
questionFour:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
},
{
questionFive:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
},
{
questionSix:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
},
{
questionSeven:
{
answers:
{
answerOne: li1,
answerTwo: li2,
answerThree: li3,
answerFour: li4
}
}
}
];
CodePudding user response:
If I understood your question correctly I think this answer might help you;
- You have to change the structure of your object to make it universal.
- You can go through your object array in which each object refers to the object of the 4 answers.
- Loop to access the 4 possible answers.
This is how I would do it:
var list = document.createElement("ol");
var li1 = document.createElement("li");
var li2 = document.createElement("li");
var li3 = document.createElement("li");
var li4 = document.createElement("li");
let choices = document.querySelector(".choices")
choices.appendChild(list)
list.appendChild(li1)
list.appendChild(li2)
list.appendChild(li3)
list.appendChild(li4)
let questionPool = [
{
answers: {
1: li1,
2: li2,
3: li3,
4: li4
}
},
{
answers: {
1: li1,
2: li2,
3: li3,
4: li4
}
},
{
answers: {
1: li1,
2: li2,
3: li3,
4: li4
}
}
];
questionPool.forEach(element => {
for(const item in element.answers){
//here you have access to the 4 li
console.log(element.answers[item]);
}
});
CodePudding user response:
I tried to refactor your code beacause most of it was repetitions for no reason, more details in the comments :
const questionEl = document.createElement('span')
const list = document.createElement("ol");
const nextBtn = document.createElement('button')
const choicesEl = document.querySelector(".choices")
nextBtn.textContent = 'Next'
choicesEl.appendChild(questionEl)
choicesEl.appendChild(list)
choicesEl.appendChild(nextBtn)
// Store you list elements by span (text of the answer) and radio (input field)
const listElements = Array.from({ length: 4 }).map(i => {
const li = document.createElement('li')
const radio = document.createElement('input')
const span = document.createElement('span')
radio.type = 'radio'
radio.name = 'quiz-radio'
li.appendChild(radio)
li.appendChild(span)
list.appendChild(li)
// for convenience
span.onclick = () => radio.click()
return { radio, span }
})
// use arrays instead of objects
const questionsPool = [
{
question: 'What is the formula for water ?',
right: 0,
answers: [
'H2O',
'NH3',
'CO2',
'C6H12O6',
]
}, {
question: 'What color is the sky ?',
right: 1,
answers: [
'blue',
'skyblue',
'lightblue',
'navyblue',
]
}
]
let score = 0
let questionIndex = 0
// update the texts in the spans
const updateQuestion = () => {
const { question, answers } = questionsPool[questionIndex]
questionEl.textContent = question
for (let i = 0; i < 4; i )
listElements[i].span.textContent = answers[i]
}
// inital rendering
updateQuestion()
nextBtn.onclick = () => {
// if the user selected the right answer : increment his score
if (listElements[questionsPool[questionIndex].right].radio.checked) score
// if there is remaining question
if (questionIndex 1 < questionsPool.length) {
// go to the next one and update texts
questionIndex
updateQuestion()
}
else
// show the final user score
console.log({ score })
}
<div ></div>
Hope it helped you !