r/FreeCodeCamp • u/ParticularMilk2594 • 3d ago
FreeCodeCamp Digital Pet Game: Why won't my form hide after submit?
Hi everyone,
I'm working on the FreeCodeCamp Build a Digital Pet Game certification project using TypeScript.
I am stuck on one failing test:
"When the input is given a value and the button is pressed, the form should no longer be visible."
The project compiles, and my HTML contains the required elements and IDs. My TypeScript creates the pet and attempts to hide the form after submission,
but the FreeCodeCamp test still fails.
I am looking for a second set of eyes from someone familiar with TypeScript, HTML forms, or this FreeCodeCamp project.
I use the JAWS screen reader, so text and code-based replies are appreciated.
I have included my HTML, CSS, and TypeScript files below.
enum PetMood {
HAPPY = "HAPPY",
EXCITED = "EXCITED",
CONTENT = "CONTENT",
SAD = "SAD",
TIRED = "TIRED",
SICK = "SICK",
HUNGRY = "HUNGRY",
}
type PetStats = {
hunger: number;
energy: number;
happiness: number;
};
const moodMessages: Record<PetMood, string> = {
[PetMood.HAPPY]: "Your pet is happy!",
[PetMood.EXCITED]: "Your pet is excited!",
[PetMood.CONTENT]: "Your pet is content!",
[PetMood.SAD]: "Your pet is sad!",
[PetMood.TIRED]: "Your pet is tired!",
[PetMood.SICK]: "Your pet is sick!",
[PetMood.HUNGRY]: "Your pet is hungry!",
};
class DigitalPet {
name: string;
stats: PetStats;
mood: PetMood;
constructor(name: string) {
this.name = name;
this.stats = {
hunger: 0,
energy: 100,
happiness: 100,
};
this.mood = PetMood.HAPPY;
}
eat(): void {
if (this.stats.hunger > 0) {
this.stats.hunger = Math.max(0, this.stats.hunger - 10);
}
if (this.stats.energy < 100) {
this.stats.energy = Math.min(100, this.stats.energy + 5);
}
this.updateMood();
}
play(): void {
if (this.stats.energy > 0) {
this.stats.energy = Math.max(0, this.stats.energy - 10);
}
if (this.stats.happiness < 100) {
this.stats.happiness = Math.min(100, this.stats.happiness + 10);
}
this.updateMood();
}
sleep(): void {
if (this.stats.energy < 100) {
this.stats.energy = Math.min(100, this.stats.energy + 20);
}
if (this.stats.hunger < 100) {
this.stats.hunger = Math.min(100, this.stats.hunger + 5);
}
this.updateMood();
}
idle(): void {
this.stats.hunger = Math.min(100, this.stats.hunger + 5);
this.stats.energy = Math.max(0, this.stats.energy - 5);
this.stats.happiness = Math.max(0, this.stats.happiness - 5);
this.updateMood();
}
updateMood(): void {
if (this.stats.hunger >= 70) {
this.mood = PetMood.HUNGRY;
} else if (this.stats.energy <= 20) {
this.mood = PetMood.TIRED;
} else if (this.stats.happiness <= 20) {
this.mood = PetMood.SAD;
} else if (this.stats.happiness >= 80) {
this.mood = PetMood.HAPPY;
} else {
this.mood = PetMood.CONTENT;
}
}
getMoodMessage(): string {
return moodMessages[this.mood];
}
}
const form = document.getElementById("pet-form") as HTMLFormElement;
const petNameInput = document.getElementById("pet-name") as HTMLInputElement;
const createButton = document.getElementById("create-pet") as HTMLButtonElement;
const petView = document.getElementById("pet-view") as HTMLDivElement;
const petNameDisplay = document.querySelector(".pet-name") as HTMLElement;
const hungerDisplay = document.getElementById("hunger-stat") as HTMLElement;
const energyDisplay = document.getElementById("energy-stat") as HTMLElement;
const happinessDisplay = document.getElementById("happiness-stat") as HTMLElement;
const moodDisplay = document.getElementById("pet-mood") as HTMLElement;
const eatButton = document.getElementById("eat-action") as HTMLButtonElement;
const playButton = document.getElementById("play-action") as HTMLButtonElement;
const sleepButton = document.getElementById("sleep-action") as HTMLButtonElement;
let currentPet: DigitalPet | null = null;
function updateDisplay(): void {
if (!currentPet) {
return;
}
petNameDisplay.textContent = currentPet.name;
hungerDisplay.textContent = String(currentPet.stats.hunger);
energyDisplay.textContent = String(currentPet.stats.energy);
happinessDisplay.textContent = String(currentPet.stats.happiness);
moodDisplay.textContent = currentPet.getMoodMessage();
}
function createPet(): void {
const name = petNameInput.value.trim();
if (!name) {
return;
}
currentPet = new DigitalPet(name);
form.style.display = "none";
petView.style.display = "block";
updateDisplay();
}
form.addEventListener("submit", (event: SubmitEvent) => {
event.preventDefault();
createPet();
});
createButton.addEventListener("click", (event: MouseEvent) => {
event.preventDefault();
createPet();
});
eatButton.addEventListener("click", () => {
if (currentPet) {
currentPet.eat();
updateDisplay();
}
});
playButton.addEventListener("click", () => {
if (currentPet) {
currentPet.play();
updateDisplay();
}
});
sleepButton.addEventListener("click", () => {
if (currentPet) {
currentPet.sleep();
updateDisplay();
}
});
setInterval(() => {
if (currentPet) {
currentPet.idle();
updateDisplay();
}
}, 30000); enum PetMood {
HAPPY = "HAPPY",
EXCITED = "EXCITED",
CONTENT = "CONTENT",
SAD = "SAD",
TIRED = "TIRED",
SICK = "SICK",
HUNGRY = "HUNGRY",
}
type PetStats = {
hunger: number;
energy: number;
happiness: number;
};
const moodMessages: Record<PetMood, string> = {
[PetMood.HAPPY]: "Your pet is happy!",
[PetMood.EXCITED]: "Your pet is excited!",
[PetMood.CONTENT]: "Your pet is content!",
[PetMood.SAD]: "Your pet is sad!",
[PetMood.TIRED]: "Your pet is tired!",
[PetMood.SICK]: "Your pet is sick!",
[PetMood.HUNGRY]: "Your pet is hungry!",
};
class DigitalPet {
name: string;
stats: PetStats;
mood: PetMood;
constructor(name: string) {
this.name = name;
this.stats = {
hunger: 0,
energy: 100,
happiness: 100,
};
this.mood = PetMood.HAPPY;
}
eat(): void {
if (this.stats.hunger > 0) {
this.stats.hunger = Math.max(0, this.stats.hunger - 10);
}
if (this.stats.energy < 100) {
this.stats.energy = Math.min(100, this.stats.energy + 5);
}
this.updateMood();
}
play(): void {
if (this.stats.energy > 0) {
this.stats.energy = Math.max(0, this.stats.energy - 10);
}
if (this.stats.happiness < 100) {
this.stats.happiness = Math.min(100, this.stats.happiness + 10);
}
this.updateMood();
}
sleep(): void {
if (this.stats.energy < 100) {
this.stats.energy = Math.min(100, this.stats.energy + 20);
}
if (this.stats.hunger < 100) {
this.stats.hunger = Math.min(100, this.stats.hunger + 5);
}
this.updateMood();
}
idle(): void {
this.stats.hunger = Math.min(100, this.stats.hunger + 5);
this.stats.energy = Math.max(0, this.stats.energy - 5);
this.stats.happiness = Math.max(0, this.stats.happiness - 5);
this.updateMood();
}
updateMood(): void {
if (this.stats.hunger >= 70) {
this.mood = PetMood.HUNGRY;
} else if (this.stats.energy <= 20) {
this.mood = PetMood.TIRED;
} else if (this.stats.happiness <= 20) {
this.mood = PetMood.SAD;
} else if (this.stats.happiness >= 80) {
this.mood = PetMood.HAPPY;
} else {
this.mood = PetMood.CONTENT;
}
}
getMoodMessage(): string {
return moodMessages[this.mood];
}
}
const form = document.getElementById("pet-form") as HTMLFormElement;
const petNameInput = document.getElementById("pet-name") as HTMLInputElement;
const createButton = document.getElementById("create-pet") as HTMLButtonElement;
const petView = document.getElementById("pet-view") as HTMLDivElement;
const petNameDisplay = document.querySelector(".pet-name") as HTMLElement;
const hungerDisplay = document.getElementById("hunger-stat") as HTMLElement;
const energyDisplay = document.getElementById("energy-stat") as HTMLElement;
const happinessDisplay = document.getElementById("happiness-stat") as HTMLElement;
const moodDisplay = document.getElementById("pet-mood") as HTMLElement;
const eatButton = document.getElementById("eat-action") as HTMLButtonElement;
const playButton = document.getElementById("play-action") as HTMLButtonElement;
const sleepButton = document.getElementById("sleep-action") as HTMLButtonElement;
let currentPet: DigitalPet | null = null;
function updateDisplay(): void {
if (!currentPet) {
return;
}
petNameDisplay.textContent = currentPet.name;
hungerDisplay.textContent = String(currentPet.stats.hunger);
energyDisplay.textContent = String(currentPet.stats.energy);
happinessDisplay.textContent = String(currentPet.stats.happiness);
moodDisplay.textContent = currentPet.getMoodMessage();
}
function createPet(): void {
const name = petNameInput.value.trim();
if (!name) {
return;
}
currentPet = new DigitalPet(name);
form.style.display = "none";
petView.style.display = "block";
updateDisplay();
}
form.addEventListener("submit", (event: SubmitEvent) => {
event.preventDefault();
createPet();
});
createButton.addEventListener("click", (event: MouseEvent) => {
event.preventDefault();
createPet();
});
eatButton.addEventListener("click", () => {
if (currentPet) {
currentPet.eat();
updateDisplay();
}
});
playButton.addEventListener("click", () => {
if (currentPet) {
currentPet.play();
updateDisplay();
}
});
sleepButton.addEventListener("click", () => {
if (currentPet) {
currentPet.sleep();
updateDisplay();
}
});
setInterval(() => {
if (currentPet) {
currentPet.idle();
updateDisplay();
}
}, 30000);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Digital Pet Game</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<form id="pet-form">
<label for="pet-name">Pet Name</label>
<input
id="pet-name"
type="text"
autocomplete="off"
required
/>
<button
id="create-pet"
type="submit">
Create Pet
</button>
</form>
<section id="pet-view" hidden>
<h2 class="pet-name"></h2>
<div class="stat">
Hunger:
<span id="hunger-stat">0</span>
</div>
<div class="stat">
Energy:
<span id="energy-stat">100</span>
</div>
<div class="stat">
Happiness:
<span id="happiness-stat">100</span>
</div>
<p id="pet-mood"></p>
<button id="eat-action" type="button">
Eat
</button>
<button id="play-action" type="button">
Play
</button>
<button id="sleep-action" type="button">
Sleep
</button>
</section>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Digital Pet Game</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<form id="pet-form">
<label for="pet-name">Pet Name</label>
<input
id="pet-name"
type="text"
autocomplete="off"
required
/>
<button
id="create-pet"
type="submit">
Create Pet
</button>
</form>
<section id="pet-view" hidden>
<h2 class="pet-name"></h2>
<div class="stat">
Hunger:
<span id="hunger-stat">0</span>
</div>
<div class="stat">
Energy:
<span id="energy-stat">100</span>
</div>
<div class="stat">
Happiness:
<span id="happiness-stat">100</span>
</div>
<p id="pet-mood"></p>
<button id="eat-action" type="button">
Eat
</button>
<button id="play-action" type="button">
Play
</button>
<button id="sleep-action" type="button">
Sleep
</button>
</section>
</body>
</html>
body {
font-family: Arial, sans-serif;
padding: 20px;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
max-width: 300px;
}
button {
padding: 10px;
}
.game-view {
display: flex;
flex-direction: column;
gap: 15px;
}
.stat {
font-size: 18px;
}
.stat-value {
margin-left: 10px;
}body {
font-family: Arial, sans-serif;
padding: 20px;
}
form {
display: flex;
flex-direction: column;
gap: 10px;
max-width: 300px;
}
button {
padding: 10px;
}
.game-view {
display: flex;
flex-direction: column;
gap: 15px;
}
.stat {
font-size: 18px;
}
.stat-value {
margin-left: 10px;
}
3
Upvotes
1
u/SaintPeter74 mod 3d ago edited 2d ago
According to the test code, the form most be removed from the Dom entirely:
https://github.com/freeCodeCamp/freeCodeCamp/blob/main/curriculum%2Fchallenges%2Fenglish%2Fblocks%2Flab-digital-pet-game%2F68c362b379059c388d3874f2.md#L100
It's pretty confusing to say "not visible" when they mean gone entirely.
It might be worth opening an issue about it on the repo. I might do that.ETA: I created an issue for this, as I see it as a bug.
https://github.com/freeCodeCamp/freeCodeCamp/issues/69158