:white_check_mark: See who is online
:white_check_mark: Enter a (user)name via Sockets.io
:white_check_mark: Fill in trivia questions form API
:white_check_mark: See how many questions are answered correctly
:white_check_mark: Answered question can not be adjusted
:white_check_mark: Results list
:white_check_mark: Remember who are online
In this Web App you can make a music quiz with trivia questions. There are a view things I would like to highlight.
At the beginning, the user is asked to fill in their name. This can be any name they want: their real name, a nickname or a made up name. Once the user filled in their name, the questions are shown and they can start making the quiz.
Once the user filled in their name, the user is online through the name socket. All users have a list of online users that will be updated everytime someone starts their game. The users can also see users that logged in before them. I did this by storing them in an 'online'-array. I push the filled in name and socket-id in this array. The user also sees it, when someone leaves the website. This is done with the user left socket
At first, the first answer was always the right one, because I render the page with EJS. This is not very nice for the quiz so I wrote a function that randomizes the order. This way you can not know which answer is the right one.
const options = document.querySelectorAll(".quiz ol li form > div")
function randomizeAnswers(){
options.forEach((answers)=>{
for (var i = answers.children.length; i >= 0; i--) {
answers.appendChild(answers.children[Math.random() * i | 0]);
}
})
}
randomizeAnswers()
When you click on an answer, you directly see if it is the right answer or not. The user sees a green or a red answer.
I did not have enough time to show the correct answer if the wrong one is answered. It would be nice for the users to see which one is right.
Every right answer (which is a radio buttons) has a class 'true'. With querySelectorAll, i select all the checked radiobuttons WITH the class 'true'. This returns a Nodelist, which is kind of an array, so the length of this list is the amount of good answers. This number is rendered on the page.
The quiz has 10 questions. So when 10 questions are filled in, the quiz is over and the ranking list will be updated with the ranking socket.
I did not have enough time to order the ranking-list. Of course this is kind of important for a ranking list. ๐
For this project I used the open Trivia API. This is a super simple API to use! Since it is an open API, you do not need an API key. The only thing you have to do is, fill in a form with question about what kind & how many question you want to fetch. Once you filled in that form, the site generates a link for you. How nice is that?! ๐
The link that i fetch, fetches 10 easy music questions. You can find the data of the questions in the results array.
{
"response_code": 0,
"results": []
}
The question-data is stored in objects. There are 2 kinds of questions: true/false-quetions & ABCD-questions
{
"category": "Entertainment: Music",
"type": "boolean",
"difficulty": "easy",
"question": "The music video to The Buggle's "Video Killed the Radio Star" was the first music video to broadcast on MTV.",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
}
{
"category": "Entertainment: Music",
"type": "multiple",
"difficulty": "easy",
"question": "Which member of the Foo Fighters was previously the drummer for Nirvana?",
"correct_answer": "Dave Grohl",
"incorrect_answers": [
"Taylor Hawkins",
"Nate Mendel",
"Chris Shiflett"
]
}
socket.on('name', (name) => {
let object = {username: name , id: socket.id}
online.push(object)
io.emit('name', {username: name , id: socket.id})
})
socket.on('name', user => {
//add item to online-list
names.insertAdjacentHTML('beforeend',
`<li id="text${user.id}">
<p>${user.username}</p>
</li>`)
//adds item to ranking
rankingList.insertAdjacentHTML('beforeend',
`<li id="${user.id}">
<p>${user.username}</p>
<p><span>Still playing...</span>/10</p>
</li>`)
})
socket.on('ranking', (ranking) => {
io.emit('ranking', {id: socket.id, amount: ranking})
})
socket.on('ranking', ranking => {
let result = document.querySelector(`#${ranking.id} p:last-of-type span`)
//update waarde in ranking lijst
let rank = ranking.amount
result.innerHTML= `${rank}`
})
socket.on('disconnect', () => {
io.emit('user left', {id: socket.id})
online = online.filter(element => {
if(element.id !== socket.id) {
// Voeg 'm toe aan de nieuwe array
return true;
} else {
// Filter 'm uit de nieuwe array
return false;
}
})
console.log('user disconnected')
})
socket.on('user left', user => {
console.log(user.id);
document.querySelector(`#text${user.id}`).remove();
})
Install and use this repo in a view simple steps
git clone https://github.com/Sophievanderburg/real-time-web-2122.git
npm install
npm run dev
http://localhost:4242/
in your favourite browser