Assignment 6 of the Front-End Web Dev bootcamp to create a timed quiz app.
Those applying for British citizenship or settlement in the UK have to take "Life in the UK" test. This quiz helps applicants test their knowledge.
"Life in the UK" quiz · GitHub repo ·Table of Contents
The goal of this project is to practice DOM manipulation and using local storage.
The tasks for this challenge are outlined in the following requirements.
The quiz app must have these features:
- A start button that when clicked a timer starts and the first question appears.
- Questions contain buttons for each answer.
- When answer is clicked, the next question appears.
- If the answer clicked was incorrect then subtract time from the clock.
- The quiz should end when all questions are answered or the timer reaches 0.
- When the game ends, it should display their score and give the user the ability to save their initials and their score.
Not mandatatory, but we were also provided with the audio files with sounds to be played when the user answers correctly or incorrectly.
We were provided with the original demo of the quiz web app:
We were provided with 3 files already built in:
I wrote the code in 3 files:
This was the most challenging assignment up to now. Mastering the concepts of DOM, ways of manipulating DOM, creating new variables for it, and storing data in local storage as JSON were quite hard. I spent most of my time studying and trying to internalize the concepts.
When I started working on the assignment, I tried to use various loops to cycle through questions and answers. I quickly realized that regular loops do not work here as they run through all iterations without stopping for user input (which is required in this case: user has to select one of the answer choices).
Once I figured out how to solve this challenge, the rest of the work was quite fast. However, I did get stuck on 2 items:
- The condition for timer === 0 did not work (it worked well for timer < 0).
- To meet the demo gif design completely, I placed buttons within list items (
li
) but was not able to remove the styling for li:nth-child(odd).
For clarity, I placed all questions and their answers in the Questions.js file, all logic in the Logic.js file, and most code related to the scores in the Scores.js file. There is some code related to scores still placed within the Logic.js file - that is because the html
elements that trigger this code are located in the Index.html file. If I were to move this code into the Scores.js file to keep the code better organized, I would have to include a link to Scores.js in the Index.html file but the task was not to touch the provided html
and css
files.
Finally (although this edge case was not specified in the requirements), the css
styling alluded that we should be able to store multiple users in local storage and display a list of users and their scores on the Highscores page Initially, I wrote the code for vanilla case (one user, always being overwritten in local storage by the latest player). But then I spent some time researching and re-writing the code to enable storing data for multiple players. I will expland more on this below.
I used this video to get an idea of how to structure the questions and answers data in the Questions.js file.
As I mentioned, this was one of the issues I was stuck on for a long time. I scheduled a session with a tutor - Sara Neves Pereira and she helped me understand the issue and re-write the code. She advised not to use list items li
but rather insert the number into the button text as i + 1
.
I copied the code for the timer function from solved files on GitLab (module 6, lesson 1, activity 10) (lines 9-33).
As I mentioned, I was stuck on the problem of timer === 0 for quite a while. I discussed it with Ben Rumbold, a colleague in the bootcamp, and he advised me to move this condition into the timer function directly. This finally solved the issue.
I wanted to store and retrieve multiple items from local storage, as this use case is closer to the real world.
This was quite a challenging issue. I researched online, but the best answer was provided to me by ChatGPT. Below are the instructions and the code I used in Logic.js on lines 122, 125, 126:
To be able to remove all user scores displayed on the Highscores page, I used the code provided in snippet 2294, Option 2A provided on StackOverflow. I used this code in Scores.js on lines 19-21.
I wanted to remove all white spaces from the user's input (initials), and to prevent the user from using numbers or punctuation symbols. The following resources were helpful to understand how to remove all white spaces and also the use of regular expressions (regex) which I used in the Logic.js file, lines 111 and 116:
- How to Remove All Whitespace from a String in JavaScript
- Check whether an input string contains a number in javascript
- What is Punct in RegEx? How to Match All Punctuation Marks in Regular Expressions
Finally, I wanted to sort the array of players' results based on the scores, in descending order. The code snippet 2193 in this discussion was very helpful and I used it in Scores.js, line 8.
My code includes an event listener on a button within a forEach
method in the Logic.js file, lines 72-91. All my attempts (and also the tutor's attempts) to take it out resulted in the code being broken.
I know that having an event listener inside a loop is not the best solution, and in fact, would cause issues in a larger program. This is something for me to keep learning and refining so that I avoid such issues in the future.
UPDATE on final challenge
I have read an article on event delegation which has greatly helped me understand both the problem and the solution. Based on this, I was able to take out the event listener and place it separately. This has resolved this issue.
The project is now live.
The deployed page looks like this:
You can find the "Life in the UK" quiz and its corresponding code here:
Attribution
- Quiz icon from Flaticon created by Vitaly Gorbachev.