/life-in-uk-quiz

Assignment 6 to practice DOM manipulation using JavaScript

Primary LanguageJavaScriptMIT LicenseMIT

Module 6 Challenge: Timed Quiz

Assignment 6 of the Front-End Web Dev bootcamp to create a timed quiz app.



Logo

'Life in the UK

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
  1. About The Project
  2. Development
  3. Deployed Project

About The Project

Project Goal

The goal of this project is to practice DOM manipulation and using local storage.

Project Specifications

The tasks for this challenge are outlined in the following requirements.

The quiz app must have these features:

  1. A start button that when clicked a timer starts and the first question appears.
  2. Questions contain buttons for each answer.
  3. When answer is clicked, the next question appears.
  4. If the answer clicked was incorrect then subtract time from the clock.
  5. The quiz should end when all questions are answered or the timer reaches 0.
  6. 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.

Sample App

We were provided with the original demo of the quiz web app:

inital screenshot

Built With

We were provided with 3 files already built in:

HTML CSS

I wrote the code in 3 files:

JavaScript

(back to top)

Development

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.

Data structure for questions and answers

I used this video to get an idea of how to structure the questions and answers data in the Questions.js file.

Numbered answer options

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.

Timer code

I copied the code for the timer function from solved files on GitLab (module 6, lesson 1, activity 10) (lines 9-33).

Timer condition

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.

Local storage

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:

chatgpt-instructions

chatgpt-code

Removing multiple children

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.

Logic checks for initials

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:

Sort array of objects

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.

Final challenge

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.

(back to top)

Deployed project

The project is now live.

Deployed application

The deployed page looks like this:

Deployed page

Links to deployed project

You can find the "Life in the UK" quiz and its corresponding code here:

(back to top)

Credit:

Attribution