Build an RPG Creature Search App Project - Build an RPG Creature Search App

Tell us what’s happening:

I am stuck on 14. of this project: When the #search-input element contains the value Red and the #search-button element is clicked, an alert should appear with the text “Creature not found”

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="styles.css">
	<title>Creature Search App</title>
</head>
<body>
	
	<div>
	<input id="search-input" required="input">
	<button id="search-button">Search</button>
	</div>

	<div class="overview"> overview
	<h3 id="creature-name"></h3>
	<h3 id="creature-id"></h3>
	<p id="weight">weight</p>
	<p id="height">height</p>
	<p id="types">types</p>
	<p id="hp">hp</p>
</div>
	<table>
	<div class="stats"> Stats
	<p id="attack">attack</p>
	<p id="defense">defense</p>
	<p id="special-attack">special-attack</p>
	<p id="special-defense">special-defense</p>
	<p id="speed">speed</p>
	</div>
	</table>

	<script src="/script.js"></script>
</body>
</html>
/* file: styles.css */

/* file: script.js */
const searchInput = document.getElementById("search-input");
const searchBtn = document.getElementById("search-button");
const creatureName = document.getElementById("creature-name");
const creatureId = document.getElementById("creature-id");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const types = document.getElementById("types");
const hp = document.getElementById("hp");
const attack = document.getElementById("attack");
const defense = document.getElementById("defense");
const specialAttack = document.getElementById("special-attack");
const specialDefense = document.getElementById("special-defense");
const speed = document.getElementById("speed");

const getCreature = async () => {
  try {
    const creatureNameorId = searchInput.value.toLowerCase();
  
    const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${creatureNameorId}`);
    const data = await res.json();


    setCreatureInfo(data);
  } catch (err) {
    alert("Creature not found");
    console.error(err);
  }
};

const setCreatureInfo = data => {
  const {creatureName,creatureId,weight,height,hp,attack,defense,specialAttack,specialDefense,speed} = data;

  creatureName.textContent = `${creatureName[0].toUpperCase() + creatureName.splice(1)}` 
  creatureId.textContent = `#${id}`;
  weight.textContent = `weight: ${weight}`;
  height.textContent = `height: ${height}`;

  hp.textContent = data.stats.hp;
  attack.textContent = data.stats.attack;
  defense.textContent = data.stats.defense;
  specialAttack.textContent = data.stats.specialAttack;
  specialDefense.textContent = data.stats.specialDefense;
  speed.textContent = data.stats.speed;

  creatureTypes.innerHTML = types.map(obj => `<span>${obj.type.name[0].toUpperCase() + obj.type.name.slice(1)}</span>`).join(" ");
};

searchBtn.addEventListener("click", e => {
  e.preventDefault();
  getCreature();
});

searchInput.addEventListener("keydown", e => {
  if(e.key === "Enter") {
    searchBtn.click();
  }
});

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/142.0

Challenge Information:

Build an RPG Creature Search App Project - Build an RPG Creature Search App

1 Like

Hi @jamesbond

Try appending a period as the first value in the src attribute.

Happy coding

damn smh lol. You are real one. I appreciate you.

Tell us what’s happening:

part 15 is still not passing. I can’t figure out whats not connecting.

When the #search-input element contains the value Pyrolynx and the #search-button element is clicked, the values in the #creature-name, #creature-id, #weight, #height, #hp, #attack, #defense, #special-attack, #special-defense, and #speed elements should be PYROLYNX, #1 or 1, Weight: 42 or 42, Height: 32 or 32, 65, 80, 50, 90, 55, and 100, respectively.

Your code so far

<!-- file: index.html -->
<!-- file: index.html -->
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1">
	<link rel="stylesheet" href="styles.css">
	<title>Creature Search App</title>
</head>
<body>
	
	<div>
	<input id="search-input" required="input">
	<button id="search-button">Search</button>
	</div>

	<div class="overview"> overview
	<h3 id="creature-name"></h3>
	<h3 id="creature-id"></h3>
	<p id="weight">weight</p>
	<p id="height">height</p>
	<p id="types">types</p>
	<p id="hp">hp</p>
</div>
	<table>
	<div class="stats"> Stats
	<p id="attack">attack</p>
	<p id="defense">defense</p>
	<p id="special-attack">special-attack</p>
	<p id="special-defense">special-defense</p>
	<p id="speed">speed</p>
	</div>
	</table>

	<script src="./script.js"></script>
</body>
</html>
/* file: styles.css */

/* file: script.js */
const searchInput = document.getElementById("search-input");
const searchBtn = document.getElementById("search-button");
const creatureName = document.getElementById("creature-name");
const creatureId = document.getElementById("creature-id");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const types = document.getElementById("types");
const hp = document.getElementById("hp");
const attack = document.getElementById("attack");
const defense = document.getElementById("defense");
const specialAttack = document.getElementById("special-attack");
const specialDefense = document.getElementById("special-defense");
const speed = document.getElementById("speed");

const getCreature = async () => {
  try {
    const creatureNameorId = searchInput.value.trim();

    const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${creatureNameorId.toLowerCase}`);
    const data = await res.json();

    setCreatureInfo(data);
  } catch (err) {
    alert("Creature not found");
  
  }
};

const setCreatureInfo = data => {
  const {creatureName,creatureId,weight,height,hp,attack,defense,specialAttack,specialDefense,speed} = data;

  // weight and height
  creatureName.textContent = `${creatureName[0].toUpperCase() + creatureName.slice(1)}` 
  creatureId.textContent = `#${id}`;
  weight.textContent = `weight: ${weight}`;
  height.textContent = `height: ${height}`;

  //stats
  const s = data.stats || {};
  hp.textContent = readStat(s, ["hp", "HP"]);
  attack.textContent = readStat(s, ["attack"]);
  defense.textContent = readStat(s, ["defense"]);
  specialAttack.textContent = readStat(s, ["special-attack", "specialAttack", "special_attack"]);
  specialDefense.textContent = readStat(s, ["special-defense", "specialDefense", "special_defense"]);
  speed.textContent = readStat(s, ["speed"]);
  
//types
  creatureTypes.innerHTML = types.map(obj => `<span>${obj.type.name[0].toUpperCase() + obj.type.name.slice(1)}</span>`).join(" ");
};

searchBtn.addEventListener("click", e => {
  e.preventDefault();
  getCreature();
});

searchInput.addEventListener("keydown", e => {
  if(e.key === "Enter") {
    searchBtn.click();
  }
});

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/142.0

Challenge Information:

Build an RPG Creature Search App Project - Build an RPG Creature Search App

Is that complete code? There seem like something might be missing - ie. readStat function does not appear to be anywhere.

Have you checked if you are getting the expected data from api?

I’ve edit the code and I am still having an issue passing 15. here’s what I have done:

const searchInput = document.getElementById(“search-input”);

const searchBtn = document.getElementById(“search-button”);

const creatureName = document.getElementById(“creature-name”);

const creatureId = document.getElementById(“creature-id”);

const weight = document.getElementById(“weight”);

const height = document.getElementById(“height”);

const types = document.getElementById(“types”);

const hp = document.getElementById(“hp”);

const attack = document.getElementById(“attack”);

const defense = document.getElementById(“defense”);

const specialAttack = document.getElementById(“special-attack”);

const specialDefense = document.getElementById(“special-defense”);

const speed = document.getElementById(“speed”);

const getCreature = async () => {

try {

const creatureNameorId = searchInput.value.trim();

const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${creatureNameorId.toLowerCase()}\`);

const data = await res.json();

setCreatureInfo(data);

} catch (err) {

alert("Creature not found");

}

};

const setCreatureInfo = (data) => {

const { name, id, weight, height, stats, types: creatureTypes } = data;

// Name and ID

creatureName.textContent = `${name[0].toUpperCase() + name.slice(1)}`;

creatureId.textContent = `#${id}`;

// Weight and Height

weight.textContent = `Weight: ${weight}`;

height.textContent = `Height: ${height}`;

// Stats handling

function readStat(stats, keys) {

for (const key of keys) {

if (stats[key] !== undefined) return stats[key];

}

return “”;

}

const s = stats || {};

hp.textContent = `HP: ${readStat(s, [“hp”, “HP”])}`;

attack.textContent = `Attack: ${readStat(s, [“attack”])}`;

defense.textContent = `Defense: ${readStat(s, [“defense”])}`;

specialAttack.textContent = `Special Attack: ${readStat(s, [“special-attack”, “specialAttack”, “special_attack”])}`;

specialDefense.textContent = `Special Defense: ${readStat(s, [“special-defense”, “specialDefense”, “special_defense”])}`;

speed.textContent = `Speed: ${readStat(s, [“speed”])}`;

// Types handling

while (types.firstChild) {

types.removeChild(types.firstChild);

}

if (Array.isArray(creatureTypes)) {

const typeNames = creatureTypes

.map((t) => {

if (typeof t === “string”) return t;

if (t && typeof t === “object”) {

if (t.type && t.type.name) return t.type.name;

if (t.name) return t.name;

}

return “”;

})

.filter(Boolean);

typeNames.forEach((tn) => {

const li = document.createElement(“li”);

  li.textContent = tn.toUpperCase();

  types.appendChild(li);

});

}

};

searchBtn.addEventListener(“click”, (e) => {

e.preventDefault();

getCreature();

});

searchInput.addEventListener(“keydown”, (e) => {

if (e.key === “Enter”) {

e.preventDefault();

getCreature();

}

});

can you please post your code again making sure it goes inside a code block? (you can use the </> button for that)

const searchInput = document.getElementById("search-input");
const searchBtn = document.getElementById("search-button");
const creatureName = document.getElementById("creature-name");
const creatureId = document.getElementById("creature-id");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const types = document.getElementById("types");
const hp = document.getElementById("hp");
const attack = document.getElementById("attack");
const defense = document.getElementById("defense");
const specialAttack = document.getElementById("special-attack");
const specialDefense = document.getElementById("special-defense");
const speed = document.getElementById("speed");

const getCreature = async () => {
  try {
    const creatureNameorId = searchInput.value.trim();

    const res = await fetch(`https://rpg-creature-api.freecodecamp.rocks/api/creature/${creatureNameorId.toLowerCase()}`);
    const data = await res.json();

    setCreatureInfo(data);
  } catch (err) {
    alert("Creature not found");
  }
};

const setCreatureInfo = (data) => {
  const { name, id, weight, height, stats, types: creatureTypes } = data;

  // Name and ID
  creatureName.textContent = `${name[0].toUpperCase() + name.slice(1)}`;
  creatureId.textContent = `#${id}`;

  // Weight and Height
  weight.textContent = `Weight: ${weight}`;
  height.textContent = `Height: ${height}`;

  // Stats handling
  function readStat(stats, keys) {
    for (const key of keys) {
      if (stats[key] !== undefined) return stats[key];
    }
    return "";
  }

  const s = stats || {};
  hp.textContent = `HP: ${readStat(s, ["hp", "HP"])}`;
  attack.textContent = `Attack: ${readStat(s, ["attack"])}`;
  defense.textContent = `Defense: ${readStat(s, ["defense"])}`;
  specialAttack.textContent = `Special Attack: ${readStat(s, ["special-attack", "specialAttack", "special_attack"])}`;
  specialDefense.textContent = `Special Defense: ${readStat(s, ["special-defense", "specialDefense", "special_defense"])}`;
  speed.textContent = `Speed: ${readStat(s, ["speed"])}`;

  // Types handling
  while (types.firstChild) {
    types.removeChild(types.firstChild);
  }

  if (Array.isArray(creatureTypes)) {
    const typeNames = creatureTypes
      .map((t) => {
        if (typeof t === "string") return t;
        if (t && typeof t === "object") {
          if (t.type && t.type.name) return t.type.name;
          if (t.name) return t.name;
        }
        return "";
      })
      .filter(Boolean);

    typeNames.forEach((tn) => {
      const li = document.createElement("li");
      li.textContent = tn.toUpperCase();
      types.appendChild(li);
    });
  }
};

searchBtn.addEventListener("click", (e) => {
  e.preventDefault();
  getCreature();
});

searchInput.addEventListener("keydown", (e) => {
  if (e.key === "Enter") {
    e.preventDefault();
    getCreature();
  }
});

Take a look ie. at this line:

What is happening in it?

Also, if there would be added printing to console of the err, when alert is displayed, it could give some information about issues causing error.