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

Tell us what’s happening:

Test 21 failed, but I get no errors and the correct text is displayed. I don’t see how the url for the creature wrong. If anyone can help me understand why I would appreciate it, thank you.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="./styles.css">
  </head>
  <body>
    <h1>RPG Creature Search</h1>
    <input id="search-input", required >
    <button id="search-button">Search</button>
    <div id="creature-name"></div>
    <div id="creature-id"></div>
    <div id="weight"></div>
    <div id="height"></div>
    <div id="types"></div>
    <div id="hp"></div>
    <div id="attack"></div>
    <div id="defense"></div>
    <div id="special-attack"></div>
    <div id="special-defense"></div>
    <div id="speed"></div>
    <script src="./script.js"></script>
  </body>
</html>
/* file: script.js */
const input = document.getElementById("search-input");
const searchBtn = document.getElementById("search-button");
const allDiv = document.querySelectorAll("div");
const typeDiv = document.getElementById("types");

//urls
const dataUrl = "https://rpg-creature-api.freecodecamp.rocks/api/creatures";
const creatureUrl = "https://rpg-creature-api.freecodecamp.rocks/api/creature/";

async function getData() {
  try {
    const response = await fetch(dataUrl);
    const data = await response.json();
    return data;
  } catch (err) {
    console.error("Creature Arrary Fetch Error: ", err);
    return null;
  }
}

async function creatureStats(creature) {
  const url = creatureUrl + strParse(creature.id);
  console.log(url)
  try {
    const response = await fetch(url);
    const data = await response.json();
    return data;
  } catch (err) {
    console.error("Creature Stat Fetch Error: ", err);
  }
}

function getIdName(arr) {
  let hasName = false;
  arr.forEach(creature => {
    if (strParse(creature["name"]) === strParse(input.value) || strParse(creature["id"]) === strParse(input.value)) {
      hasName = true;
      return;
    }
  });
  if (hasName) {
    return strParse(input.value);
  } else {
    alert("Creature not found");
    return;
  }
}

function strParse(str) {
  return str.toString().trim().toLowerCase();
}

function getCreature(data, idName) {
  let creatureObj;
  data.forEach(monster => {
    if (strParse(monster.id) === idName || strParse(monster.name) === idName) {
      creatureObj = monster;
    }
  });
  return creatureObj;
}

function displayData(data) {
  allDiv.forEach(div => {
    switch (div["id"]) {
      case "creature-name":
        div.textContent = data["name"];
        break;
      case "creature-id":
        div.textContent = data["id"];
        break;
      case "weight":
        div.textContent = data["weight"];
        break;
      case "height":
        div.textContent = data["height"];
        break;
      case "types":
        const arr = [];
        let strArr = [];
        data["types"].forEach(type => {
          const text = type["name"].toUpperCase();
          arr.push(text);
        });
        arr.forEach(e => {
          strArr.push(`<div>${e}</div>`)
        });
        div.innerHTML = strArr.join("");
        break;
      case "hp":
        data["stats"].forEach(stat => {
          if (stat["name"] === "hp") {
            div.textContent = stat["base_stat"];
          }
        });
        break;
      case "attack":
        data["stats"].forEach(stat => {
          if (stat["name"] === "attack") {
            div.textContent = stat["base_stat"];
          }
        });
        break;
      case "defense":
        data["stats"].forEach(stat => {
          if (stat["name"] === "defense") {
            div.textContent = stat["base_stat"];
          }
        });
        break;
      case "special-attack":
        data["stats"].forEach(stat => {
          if (stat["name"] === "special-attack") {
            div.textContent = stat["base_stat"];
          }
        });
        break;
      case "special-defense":
        data["stats"].forEach(stat => {
          if (stat["name"] === "special-defense") {
            div.textContent = stat["base_stat"];
          }
        });
        break;
      case "speed":
        data["stats"].forEach(stat => {
          if (stat["name"] === "speed") {
            div.textContent = stat["base_stat"];
          }
        });
        break;
    }
  });
}

function search() {
  
  getData().then(dataArr => {
    let idName = getIdName(dataArr);
    if(idName) {
      let creatureObj = getCreature(dataArr, idName);
      creatureStats(creatureObj).then(data => {
        displayData(data);
      });
    }
  });
  typeDiv.innerHTML = "";
  
}

searchBtn.addEventListener("click", () => {
  search();
});

/* file: styles.css */
 body {
   text-align: center;
 }

 div {
   height: 50px;
   width: 50px;
 }

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36

Challenge Information:

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

Welcome back to the forum @Xander

I can only search for certain uppecase Pokemon, or only those whose id ranges from 1 to 19.

Creature not found should not occur for Pikachu

Happy coding

yes it should, there are no Pokemon (anymore) in this app

you call your dataUrl after the button is clicked. Do you need to do that each time the button is clicked? what’s the use for that? the data from that url don’t change based on the user input

Thank you all for your replies. I solved the issue by only fetching data for the creature searched for. Then checking if the url is valid creature before displaying the data.

if it’s not a valid creture you get a 404 error from the API

Yes, and you can check the HTML status code of the response and display an alert if it is a 404.