1

I'm trying to build a basic quiz, and am having difficulty with the final part: After the last question has been answered, i want to alert("end of quiz") and reset the variables back to 0.

I have put: if question number is larger than array of questions' length, output "end of quiz".. but it only outputs this after a secondary click after the quiz has ended.. Now if i put it as = to question's length it outputs this alert a question too soon.

Can someone please explain if i am going about the right way? And is there a way to solve this in the way I have written it without rewriting all the logic? I am sure there are way more efficient ways of doing this I would really like to know how to improve my approach.

(If you open the snippet fullscreen the button is not hidden by the error)

//JSON style data
var allQuestions = [
    { 
        question: "Who is Prime Minister of the United Kingdom?", 
        choices: ["David Cameron", "Gordon Brown", "Winston Churchill", "Tony Blair"], 
        correctAnswer: 0 
    },
    {
        question: "What is your favourite colour?",
        choices: ["Green", "Brown", "Blue", "Red"],
        correctAnswer: 0
    },
    {
        question: "Who is your name?",
        choices: ["Bob", "Paul", "Andrey", "Alex"],
        correctAnswer: 0
    },
];


//VARIABLES
var question = document.querySelector('.questionX');
var questionNumber = 0;
var answer = document.querySelector('.userAnswer');
var score = 0;


//FUNCTION EXPRESSION TO UPDATE THE DOM WITH TEXT
let updateText = function(){

    if (typeof allQuestions[questionNumber].question !== 'undefined') {
        // the question is defined & exists
        question.innerHTML = allQuestions[questionNumber].question


        for (i = 0; i < allQuestions[questionNumber].choices.length; i++) {

            //ADD AN OPTION ELEMENT WITH innerHTML of allQuestions[questionNumber].choices[i] and a value equal to the count of the loop.
            var newOption = document.createElement("option")

            newOption.appendChild(document.createTextNode(allQuestions[questionNumber].choices[i]))

            answer.appendChild(newOption)

            //set the value of each option element to the iteration count of the loop.
            newOption.value = i
        }
    } else return
}

//load first question on window load
window.onload = updateText();



//CLEAR THE QUESTIONS OPTIONS
let clearOptions = function (){
    while (answer.children[1]) {
        answer.removeChild(answer.children[1]);
    }
}




//onClick function for next qestion button
function nextQuestion(){

    //if questionNumber > allQuestions.length alert you scored score out of allQuestions.length and set score to 0 and question to 0 and remove & rerender possible answers.
    if (questionNumber >= allQuestions.length) {
        alert(`end of quiz, you scored ${score} out of ${allQuestions.length}`);
        score == 0;
        questionNumber == 0;
        clearOptions();
        updateText();
    }
    
    
    //else if value of answer = value of correct answer add 1 to score and add 1 to question number & remove old options & update the dropdown with new options. 
    else if (document.querySelector('.userAnswer').value == allQuestions[questionNumber].correctAnswer) {
        
        questionNumber += 1;
        alert("Yay");
        clearOptions();
        score += 1;
        updateText();

    } 
    //else alert ("ney") and stay on same question
    else{
        alert("Ney, try again")
    }

    
   
}

document.querySelector("#nextQuestion").addEventListener('click', function (){
    nextQuestion();
})
<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
        crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" media="screen" href="main.css" />


</head>

<body>
    <div class="container-fluid">
        <div class="row">
            <div class="d-flex mx-auto mt-5 mb-5">
                Quiz
            </div>
        </div>
        <div class="row">
            <div class="col-12 col-sm-6 mx-auto">
<form>
    <div class="form-group">
        <p class="questionX">What is your favourite instrument?</p>
    </div>

    <select class="userAnswer custom-select mb-3">
        <option disabled selected>Pick one</option>
        <!-- <option value="0">Guitar</option>
        <option value="1">Violin</option>
        <option value="2">Oboe</option> -->
    </select>

    
</form>

                <button type="button" id="nextQuestion" class="btn btn-primary d-flex mx-auto mt-2">Next</button>

                

            </div>
        </div>
    </div>


    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
        crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
        crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
        crossorigin="anonymous"></script>
    <script src="main.js"></script>
</body>

</html>

3
  • 1
    no that's exactly what i've tried.. there's really something to do with the order in which i am doing the logic i think but i cant wrap my head around it Commented Jan 27, 2019 at 19:24
  • == in nextQuestion() in first if block Commented Jan 27, 2019 at 19:31
  • 1
    no like i said i tried that and it still takes an extra click after that Commented Jan 27, 2019 at 19:48

1 Answer 1

1

First, fix question undefined err at the end, to do that change this:

if (typeof allQuestions[questionNumber].question !== 'undefined') 

to this:

 if (allQuestions[questionNumber] )

Then change this if:

if (questionNumber >= allQuestions.length) {
    alert(`end of quiz, you scored ${score} out of ${allQuestions.length}`);
    score == 0;
    questionNumber == 0;
    clearOptions();
    updateText();
}

to this:

if (questionNumber == allQuestions.length -1 ) {
    alert(`end of quiz, you scored ${score+1} out of ${allQuestions.length}`);
    score == 0;
    questionNumber == 0;
    clearOptions();
    // updateText(); <-- you do not need this
}

It will work as expected. Working fiddle.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes but the score starts at 0, there are 3 clicks of the button to get to the final alert, and you are adding one.. so surely the score after the third click should be 4 now?
hey do you know how i could load those variables from this json file (below) instead of the variable above??: raw.githubusercontent.com/AGrush/jsquizapp/master/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.