Simple JavaScript quiz - problem

Hi guys. I am learning JavaScript and have been following this simple quiz tutorial on youtube. However, I got somehow stuck at the startButton.addEventListener(“click”, startGame) line; when opened in my browser, there is an error in this part of the code, reminding me that Cannot read property ‘addEventListener’ of null

I can’t figure out why this is happening :thinking: If anyone has any idea, please let me know and thank you so much! :slight_smile:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width", initial-scale=1.0>
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>Quiz</title>
	<link rel="stylesheet" type="text/css" href="style.css">
	<script type="text/javascript" src="quiz.js"></script>
</head>
<body>
<div class="container">
	<div id="question-container" class="hide">
		<div id="question">Question</div>
		<div id="answer-buttons" class="btn-grid">
		<button class="btn">answer1</button>
		<button class="btn">answer2</button>
		<button class="btn">answer3</button>
		<button class="btn">answer4</button>
		</div>
	</div>
	<div class="controls">
		<button id="start-btn" class="start-btn btn">Start</button>
		<button id="next-btn" class="next-btn btn hide">Next</button>
	</div>
</div>

</body>
</html>

const startButton = document.getElementById("start-btn")
const nextButton = document.getElementById("next-btn")
const questionContainerElement = document.getElementById("question-container")
let shuffledQuestions, currentQuestionIndex
const questionElement = document.getElementById("question")
const answerButtons = document.getElementById("answer-buttons")


startButton.addEventListener("click", startGame)

function startGame() {
	startButton.classList.add("hide");
	shuffledQuestions = questions.sort(() => Math.random() - .5);
	currentQuestionIndex = 0;
	questionContainerElement.classList.remove("hide");
	setNextQuestion()
}

function setNextQuestion() {
	resetState();
	showQuestion(shuffledQuestions[currentQuestionIndex]);
}

function showQuestion(question){
    questionElement.innerText = question.question;
    question.answers.forEach(answer => {
    	const button = document.createElement("button");
    	button.innerText = answer.text;
    	button.classList.add("btn");
    	if (answer.correct) {
    		button.dataset.correct = answer.correct
    	}
    	button.addEventListener("click", selectAnswer)
    	answerButtons.appendChild(button);
    })
}

function resetState() {
	nextButton.classList.add("hide");
	while (answerButtons.firstChild) {
		answerButtons.removeChild;
		(answerButtons.firstChild);
	}
}

function selectAnswer(e) {

}

const questions = [
{
	question: "Which is the smallest planet in our solar system?",
	answers: [
	       {text:"jupiter", correct:true},
	       {text:"mercury", correct:false}
	]
}
]

Also CSS:

*, ::before, *::after {
	margin: 0 auto;
	box-sizing: border-box;
}

:root {
	--hue-neutral: 200;
	--hue-wrong: 0;
	--hue-correct: 145;
}


body {
	--hue: var(--hue-neutral);
	padding: 0;
	margin: 0;
	display: flex;
	justify-content: center;
	align-items: center;
	width: 100vw;
	height: 100vh;
	background-color: hsl(var(--hue), 100%, 20%);
}

body.correct {
--hue: var(--hue-correct);
}

body.wrong {
--hue: var(--hue-wrong);
}

.container {
	width: 300px;
	max-width: 80%;
	background-color: white;
	border-radius: 5px;
	padding: 10px;
}

.btn-grid {
	display: grid;
	grid-template-columns:  repeat(2,auto);
	grid-gap: 10px;
	margin: 20px 0;
}

.btn {
	--hue: var(--hue-neutral);
	border: 1px solid hsl(var(--hue), 100%, 30%);
	background-color: hsl(var(--hue), 100%, 50%);
	border-radius: 5px;
	padding: 5px 10px;
	color: white;
	outline: none;

}

.btn:hover {
    border-color: black;
    border: 1.5px solid #000000;
}

.btn.correct {
    --hue: var(--hue-correct);
    color: black;
}

.btn.wrong {
	--hue: var(--hue-wrong);
}

.start-btn, .next-btn {
	font-size: 1.5rem;
	font-weight: bold;
	padding: 10px 20px;
}

.controls {
	display: flex;
	justify-content: center;
	align-items: center;
}

.hide {
	display: none;
}

By the look of it, you are loading your script before the DOM, this means that by the time the engine start reading your JS file, the DOM has yet to load.

So when it reads:

const startButton = document.getElementById("start-btn")

It’s highly likely that the button is not on the page yet (thus undefined) as your console suggest.

A common pattern is to wait for the DOM to load before firing any script to avoid such error.
You can listen to DOMContentLoaded for example :slight_smile:

Also is generally better to place your script tag after the markup.
Hope this helps :+1:

2 Likes

This was helpful, thank you so much :slight_smile: