Complete solution (100% reference)
index.html- Main HTML pagescript.js- JavaScript logicstyles.css- Styling and layoutpackage.json- Dependenciessetup.sh- Setup scriptREADME.md- Instructions (below)💡 Download the ZIP, extract it, and follow the instructions below to get started!
Complete Instructor Guide for All 4 Challenges
This Template Solution provides gold standard implementations for all 4 debugging challenges in Activity 12. Each challenge solution includes:
✅ Box-drawing characters for section headers ✅ Teaching comments explaining WHY, not just HOW ✅ Common student mistakes documented per challenge ✅ Edge cases and gotchas highlighted ✅ Discussion points for classroom conversation ✅ Extension challenges for advanced students ✅ Console logging for step-by-step execution ✅ Assessment rubrics for each challenge
| Challenge | Topic | Time | Key Concepts |
|---|---|---|---|
| Challenge 1 | Array Operations & Interactive Menu | 15 min | Arrays, push(), pop(), forEach(), onclick |
| Challenge 2 | DOM Manipulation | 15 min | querySelector(), createElement(), appendChild(), remove(), classList |
| Challenge 3 | Object Properties | 10 min | Object literals, property modification, type changing |
| Challenge 4 | Event Handling | 15 min | addEventListener(), mouseover, mouseout, click events |
Total Time: 55 minutes
Template Solution/
└── activity-12-debugging-challenge-b/
├── README.md (this file)
└── debugging-challenge-questions/
├── Challenge-1-Drink Menu/
│ ├── index.html
│ └── script.js
├── Challenge-2-DOM Manipulation/
│ ├── index.html
│ └── script.js
├── Challenge-3-Profile Object/
│ ├── index.html
│ └── script.js
└── Challenge-4-Button/
├── index.html
└── script.js
Location: debugging-challenge-questions/Challenge-1-Drink Menu/
let drinks = ["Coffee", "Tea", "Milo", "Horlicks", "Apple Juice"];
Teaching Points:
let (not const) because array will be modified[] for arrayslet removedDrink = drinks.pop(); // Returns "Apple Juice"
let newLength = drinks.push("Matcha"); // Returns 5
Teaching Points:
pop() returns removed elementpush() returns new array lengthdrinks.forEach((drink, index) => {
console.log(`${index}: ${drink}`);
});
Teaching Points:
() => {}function change() {
let drinkIndex = prompt("Which drink do you want to replace?");
let newDrink = prompt("What is the new drink?");
drinks[drinkIndex] = newDrink;
console.log(drinks);
}
Enhanced Version (with validation):
Infinite loops in while validation
Wrong bracket types
() or {} instead of [] for arrays[] instead of () for method callsForgetting Number() conversion
prompt() returns string, not numberNot storing forEach parameter correctly
forEach((index, drink)) ❌ (wrong order!)forEach((drink, index)) ✅ (element first)Calling function immediately in onclick
onclick="change()" vs change in addEventListener| Criteria | Points | What to Check |
|---|---|---|
| Array created with 5 elements | 10% | Correct syntax, initialized properly |
| pop() removes last element | 10% | Returns correct value, array shortened |
| push() adds element | 10% | Returns new length, array extended |
| forEach() logs each element | 15% | Arrow function, correct parameters |
| change() function works | 15% | Prompts work, array modifies, logs |
| Input validation (bonus) | 10% | Checks null, NaN, bounds, empty |
| Code quality | 30% | Comments, naming, organization |
Total: 100%
Location: debugging-challenge-questions/Challenge-2-DOM Manipulation/
const ul = document.querySelector("ul");
const newli = document.createElement("li");
newli.textContent = "Giraffe";
ul.appendChild(newli);
Teaching Points:
textContent vs innerHTML (security)appendChild() vs append() (newer method)const h2 = document.querySelector("#heading2");
h2.remove();
Teaching Points:
# for ID selectorsremove() vs removeChild() (modern vs old)const style = document.querySelector("#style");
style.classList.add("bg-warning");
style.classList.add("m-5");
Teaching Points:
classList vs className (modern vs old)Wrong selector syntax
querySelector("heading2") ❌ (missing #)querySelector("#heading2") ✅Creating wrong element
createElement("list") ❌ (no such tag)createElement("li") ✅Forgetting parentheses
h2.remove ❌ (references method)h2.remove() ✅ (calls method)Adding multiple classes wrong
classList.add("bg-warning m-5") ❌ (treats as one class with space!)classList.add("bg-warning", "m-5") ✅ (separate arguments)Not checking if element exists
if (element) { ... }| Criteria | Points | What to Check |
|---|---|---|
| querySelector() used correctly | 10% | Correct selector syntax |
| createElement() used correctly | 10% | Correct tag name |
| textContent set correctly | 5% | Text displays properly |
| appendChild() used correctly | 5% | Element appears in DOM |
| Element removed successfully | 20% | h2 no longer visible |
| bg-warning class added | 12% | Yellow background appears |
| m-5 class added | 13% | Large margin appears |
| Code quality | 15% | Comments, validation |
| Bonus: Null checking | 10% | if statements before operations |
Total: 100%
Location: debugging-challenge-questions/Challenge-3-Profile Object/
const profile = {
name: "Maya",
gender: "Female",
age: 14,
school: "Telebort"
};
Teaching Points:
{} for objects:const (prevents reassignment, allows mutation)profile.school = ["ABC Primary School", "XYZ Secondary School", "Telebort"];
Teaching Points:
const objectsWrong bracket type
const profile = [name: "Maya"] ❌ (square brackets)const profile = {name: "Maya"} ✅ (curly braces)Missing commas
Using assignment operator
{name = "Maya"} ❌ (equals sign){name: "Maya"} ✅ (colon)Trying to reassign const
profile = {...} ❌ (can't reassign const)profile.school = ... ✅ (can mutate properties)Wrong property name
profile.schools = [...] ❌ (creates NEW property)profile.school = [...] ✅ (modifies EXISTING)// ALLOWED (mutation):
const obj = { name: "Alice" };
obj.name = "Bob"; ✅ // Change property
obj.age = 25; ✅ // Add property
delete obj.name; ✅ // Remove property
// NOT ALLOWED (reassignment):
obj = { name: "Bob" }; ❌ // TypeError!
Explanation: const locks the variable binding, not the object contents!
| Criteria | Points | What to Check |
|---|---|---|
| Object created correctly | 10% | Correct syntax (braces, colons, commas) |
| name property (string) | 10% | Correct type and value |
| gender property (string) | 8% | Correct type and value |
| age property (number) | 8% | Correct type (not string!) |
| school property (string initially) | 9% | Initial string value |
| school modified to array | 20% | Correct array syntax |
| Array contains multiple schools | 10% | At least 2-3 schools |
| Object logged correctly | 5% | console.log() used |
| Code quality | 15% | Comments, organization |
| Bonus: Type checking | 5% | typeof, Array.isArray() |
Total: 100%
Location: debugging-challenge-questions/Challenge-4-Button/
const button = document.querySelector('button');
Teaching Points:
button.addEventListener('mouseover', () => {
button.classList.replace('btn-light', 'btn-warning');
});
button.addEventListener('mouseout', () => {
button.classList.replace('btn-warning', 'btn-light');
});
Teaching Points:
addEventListener() syntaxclassList.replace() vs add()/remove()button.addEventListener('click', () => {
alert('I love Telebort!');
});
Teaching Points:
Wrong event name
addEventListener('onmouseover', ...) ❌ (don't use "on" prefix)addEventListener('mouseover', ...) ✅Calling function immediately
addEventListener('click', alert('Hi')) ❌ (calls immediately!)addEventListener('click', () => alert('Hi')) ✅ (callback)Wrong classList method
classList.add('btn-warning') ⚠️ (doesn't remove old class)classList.replace('btn-light', 'btn-warning') ✅ (swaps)Forgetting quotes
addEventListener(click, ...) ❌ (undefined variable)addEventListener('click', ...) ✅ (string)Script runs before HTML loads
<script> at end of <body>DOMContentLoaded eventdefer attribute| Feature | addEventListener | onclick attribute |
|---|---|---|
| Multiple handlers | ✅ Yes | ❌ No (overwrites) |
| Separation of concerns | ✅ Yes | ❌ No (mixes HTML/JS) |
| Flexibility | ✅ High | ⚠️ Limited |
| Modern practice | ✅ Recommended | ❌ Outdated |
| Criteria | Points | What to Check |
|---|---|---|
| Button element exists in HTML | 10% | Proper HTML structure |
| Button selected correctly | 10% | querySelector() syntax |
| mouseover listener added | 10% | Event fires on hover |
| mouseout listener added | 10% | Event fires on unhover |
| classList.replace() used | 10% | Correct class swapping |
| Hover effects work | 10% | Visual color changes |
| click listener added | 10% | Event fires on click |
| Alert shows correct message | 10% | "I love Telebort!" |
| Code quality | 15% | Arrow functions, comments |
| Bonus: Element validation | 5% | if (button) check |
Total: 100%
Review Prerequisites:
Set Expectations:
Common Questions:
Monitor Progress:
Encourage Best Practices:
Differentiation:
Whole Class Discussion:
Common Misconceptions:
Real-World Applications:
Code Review Checklist:
Rubric Scoring:
Peer Review:
For Struggling Students:
"Great effort! I see you got [specific part] working. Let's focus on [problem area]. Try adding console.log() to see what's happening at each step."
For Proficient Students:
"Excellent work! All challenges complete and working. Your code is clean and well-commented. Consider trying [extension challenge] to deepen your understanding."
For Advanced Students:
"Outstanding! You've mastered all challenges and added validation. I'm impressed by [specific feature]. Next, explore [advanced topic] to prepare for upcoming projects."
| Problem | Likely Cause | Solution |
|---|---|---|
| Infinite loop | Variable not updated in loop | Check prompt() inside loop |
| "Not a function" error | Wrong syntax (brackets) | Use () for methods, not [] |
| Index out of bounds | User entered wrong number | Add validation: check index < array.length |
| Problem | Likely Cause | Solution |
|---|---|---|
| "null" error | Element doesn't exist | Check HTML, verify selector syntax |
| New item not appearing | appendChild() on wrong parent | Log ul to verify it's the list |
| Classes not applying | Wrong method or class name | Use classList.add(), check spelling |
| Problem | Likely Cause | Solution |
|---|---|---|
| Syntax error | Missing comma or colon | Check object literal syntax |
| Property not changing | Wrong property name | Verify exact property name (case-sensitive) |
| Can't reassign const | Trying to reassign whole object | Show mutation vs reassignment |
| Problem | Likely Cause | Solution |
|---|---|---|
| Button not found | Script runs before HTML loads | Move <script> to end of <body> |
| Events not firing | Wrong event name or syntax | Check event name (no "on" prefix) |
| Handler runs immediately | Called function instead of passing | Use arrow function: () => func() |
Combine Challenges:
Enhance Functionality:
New Features:
Before sharing solutions with students, verify:
v1.0 - Initial complete solution
Don't Share Immediately:
Adapt to Your Class:
Use for Professional Development:
Encourage Different Approaches:
Activity 12 | W2 Advanced JavaScript Foundations | 55 minutes
Template Solution Created: 2024 For Use By: Telebort Instructors Aligned With: W2 Course Learning Objectives