Full Stack Camp
145 subscribers
8 photos
16 files
89 links
Fullstack Camp | Learn. Build. Launch.
Welcome to the ultimate tech adventure!
Join us for a hands-on journey through HTML, CSS, JavaScript, React, Node.js, Express & MongoDB — all in one place.
Download Telegram
9. Which array method is a higher-order function?
Anonymous Quiz
17%
a) push()
83%
b) filter()
0%
c) length
0%
d) pop()
10. What will this print?
setTimeout(() => console.log("Hello"), 0);
console.log("World");
Anonymous Quiz
33%
a) Hello World
50%
b) World Hello
17%
c) Error
0%
d) Hello only
13. Which keyword is used inside a class to create objects?
Anonymous Quiz
33%
a) class
67%
b) constructor
0%
c) object
0%
d) init
16. What will this output?
for (let i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); }
Anonymous Quiz
60%
a) 0 1 2
20%
b) 3 3 3
0%
c) 0 0 0
20%
d) Error
17. What will this output?
for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 100); }
Anonymous Quiz
100%
a) 0 1 2
0%
b) 3 3 3
0%
c) 0 0 0
0%
d) Error
18. What will this print?
const obj = { name: "Code", greet: () => console.log(this.name) };
obj.greet();
Anonymous Quiz
0%
a) "Code"
100%
b) undefined
0%
c) Error
0%
d) "obj"
20. Which one is NOT a valid Promise state?
Anonymous Quiz
0%
a) pending
50%
b) fulfilled
0%
c) rejected
50%
d) aborted
21. What will this output?
Promise.resolve(1)
.then(x => x + 1) .then(x => { throw new Error("Oops") }) .catch(err => 999) .then(x => console.log(x));
Anonymous Quiz
0%
a) 1
67%
b) 2
33%
c) Error
0%
d) 999
23. What will this output?
class Animal { constructor(name) { this.name = name; } }
const a = new Animal("Dog"); console.log(typeof a);
Anonymous Quiz
33%
a) "function"
67%
b) "object"
0%
c) "class"
0%
d) "Animal"
24. Which keyword is used to inherit from another class?
Anonymous Quiz
0%
a) super
17%
b) this
17%
c) extends
67%
d) inherits
25. Which DOM method selects the first matching element?
Anonymous Quiz
0%
a) getElementById()
25%
b) getElementsByClassName()
75%
c) querySelector()
0%
d) querySelectorAll()
Project 2 — Quiz Game 🎯

Hello Campers 👋
This is Project Two, your next build after the Calculator & Digital Clock.
This Quiz Game will tie together DOM manipulation, events, timers, data handling (local arrays or API), and localStorage. Build it step-by-step, test often, and style it nicely. Below is everything you need: core + optional features, a step-by-step plan with small hints, common pitfalls, and a debugging checklist.

1) Project overview

Build an interactive multiple-choice quiz app that:
shows one question at a time,
gives instant feedback (correct / wrong),
tracks score and progress,
shows a summary at the end,
and (optionally) fetches questions from a free API for dynamic content.

2) Core features (must-have)

Start screen: title, options (number of questions, difficulty optionally), and Start button.
Question screen: question text + 3–4 clickable answer buttons.
Immediate feedback: highlight correct/incorrect answers after user selects one.
Progress: show current question number (e.g., 3 / 10).
Score tracking: update score for correct answers.
End screen / Summary: show final score, percentage, and a Restart button.
Persist high scores: save top scores ( score + date) in localStorage.

3) Optional / advanced features (stretch)
➤Fetch questions from Open Trivia DB (https://opentdb.com/api.php?amount=10&type=multiple) so the quiz changes each play.
➤Per-question timer (e.g., 10 seconds) with automatic move-on when time runs out.
➤Difficulty / Category selector (use API query params).
➤Keyboard shortcuts for answers (1–4 keys).
➤Progress bar, animations, and sound feedback.
➤Save and show top 5 high scores in a leaderboard (sort & store in localStorage).
➤Accessibility: focus management, aria-live for feedback messages.

4) Example question data model
Use this for local questions or to normalize API responses:

// normalized question object

{ question: "What is the capital of Ethiopia?",
options: ["Addis Ababa", "Bahir Dar", "Gondar", "Mekelle"],
answer: "Addis Ababa" }


If you use Open Trivia DB, map correct_answer and incorrect_answers into this shape and shuffle the options.


5) Step-by-step implementation plan (with hints)

Step 1 — HTML skeleton
➤Create visible areas (or components):
#start-screen (start button, options)
#quiz-screen (question area, options container, progress, timer)
#result-screen (final score, play again) ➤Hide/show screens by toggling a CSS class (e.g., .hidden).

Step 2 — question storage & loading
➤Start with a local questions array (hardcoded). Later add a loadQuestions() function that either:
returns the local array, or
uses fetch() to get from Open Trivia DB and maps results into your shape.

Fetch hint:

async function loadFromAPI(amount=10) {
    const res = await fetch(
https://opentdb.com/api.php?amount=${amount}&type=multiple);
   if (!res.ok) throw new Error("Network error");
   const json = await res.json(); // map json.results -> normalize objects }


Tip: API answers may include HTML entities (&quot;). Decode them using a small helper:

function decodeHTML(str){
   const el = document.createElement('textarea');
   el.innerHTML = str;
  return el.textContent; }


Step 3 — shuffle questions and options
Use the Fisher–Yates shuffle to randomize both questions and answer options (so the correct answer isn't always first).

function shuffle(arr) {
   for (let i = arr.length - 1; i > 0; i--) {
       const j = Math.floor(Math.random() * (i + 1));
       [arr[i], arr[j]] = [arr[j], arr[i]]; }
return arr; }
1
Step 4 — render a question
showQuestion(index) should:
➥set questionText.textContent = question.question
➥clear optionsContainer
➥create buttons for each option with data-answer attribute
➥attach a click handler to the options (or use event delegation on the container)
Hint: Use optionsContainer.addEventListener('click', handler) and inside handler check e.target.matches('button') to avoid many listeners.

Step 5 — handle answer selection
➥When an option is clicked:
disable further clicks until the app moves on
➥compare selected === question.answer
visually mark selected button green or red
➥update score if correct
after a short delay (e.g., 700ms) move to the next question or to results

Step 6 — timer (optional)
If using per-question timer:
display countdown and start setInterval (or setTimeout loop)
show decreasing time and when it hits 0 auto-mark the question as wrong and proceed
always clearInterval when moving on

Hint: use  const start = Date.now(); and compute Math.max(0, duration - (Date.now() - start)) for stable timing.

Step 7 — finishing & storing high score
On completion:
➤show final score and optionally percentage/time
➤ask for player name (input) to save high score
➤store high scores in localStorage as JSON array:

const scores = JSON.parse(localStorage.getItem('quizHighs') || '[]');
scores.push({ name, score, date: Date.now() });
scores.sort((a,b)=>b.score-a.score);
localStorage.setItem('quizHighs', JSON.stringify(scores.slice(0,10)));


Step 8 — polish & UX
➥Add animations to feedback (CSS classes).
➥Add keyboard support (1–4 keys to select).
➥Add a progress bar or small badges for question numbers.
➥Show a loading spinner when fetching from API.

6) Common pitfalls & how to avoid them
Duplicate event listeners: If you re-render option buttons each question, avoid re-attaching listeners repeatedly. Use event delegation on the container instead.
Not clearing timers: Forgetting clearInterval causes multiple timers running → buggy behavior.
Mutating original question array: Shuffling in-place may break reuse. Clone arrays if you need the original later (e.g., questions.slice()).
Comparing HTML-encoded strings: API answers may have &quot; etc. Always decode or normalize strings before comparing.
LocalStorage JSON errors: Always wrap JSON.parse(localStorage.getItem(...)) in try/catch in case the stored string is corrupted.
Index out of bounds: Check currentQuestionIndex before rendering; don’t try to show a question after the last index.
Poor accessibility: Not setting focus or not using aria-live for feedback makes it hard for screen-reader users.

7) Debugging checklist (step-by-step)
If something breaks, follow this checklist:
Console
Any errors? Read stack trace. Fix the first error — it often stops later code.
Network tab (if using API)
Is the fetch request returning 200? Inspect response body.
Inspect data
console.log(normalizedQuestions) after loading. Are objects shaped as you expect?
Event listeners
console.log inside click handler to ensure it fires. Use .matches() guard in delegation.
Timers
Are there multiple intervals running? console.log timer IDs and ensure clearInterval(id) executes.
Display
Are elements being hidden/shown properly? Check classList toggles.
localStorage
Verify stored JSON with JSON.parse(localStorage.getItem('quizHighs') || '[]').
Edge cases
Test: zero questions, network failure, slow API, special characters in answers.
Step isolation
If a function fails, isolate it and run in console or small snippet until it works (e.g., test shuffle separately).

Final encouragement
Start small: get one question rendering and an option click working. Then add scoring. Then timer. Then API. Build iteratively, test each step, and commit your work often. You’ve done bigger things already — you’ve got this! 🚀


💥   share your solutions in the group,
💥invite a friend,
      and as always —

💥stay well, stay curious, and stay coding ✌️