Getting into the Pokedex code - Project post 2
Published: 2023-09-17 10:22:03

Hi there, welcome back to part two of the Pokedex Project series. So far we had gotten to the pitching part of the project where we talked to our mentor to see if what we have planned was feasible and met the criteria for the project.

As mentioned previously, I had done some initial coding leading up to the pitch to better visualise in mine and the mentor's head my plan. 

##Baby code
To begin the initial coding I wanted to have that input field that would then update the table below once a Pokemon had been selected. Initial styling wasn't important as I just wanted something on a page.

Below was the HTML for that first instance:
![Initial HTML snippet](https://github.com/Danarkey/phase-1-project/blob/main/blog%20screenshots/HTML-initial.JPG?raw=true)

##Getting the JS to work
After the basic setup of the HTML document I needed to get the code to fetch the Pokemon stats from the name of the Pokemon that the user has input. So following our plan and attack methodology we need to break down the problem into each individual section and find a solution one step at a time.

1. Set up a const of when a user inputs a Pokemon
2. Fetch the stats from the API for said Pokemon
3. Update the table with the stats for each corresponding value

So from those points our initial JS code was looking a little something like this:

const apiUrl = "https://pokeapi.co/api/v2/pokemon/";
const updateStats = (selectedPokemon) => {
  fetch(apiUrl + selectedPokemon)
    .then((response) => response.json())
    .then((data) => {
      const stats = data.stats;

      stats.forEach((stat) => {
        const statName = stat.stat.name;
        const baseStat = stat.base_stat;

        const statValueElement = document.getElementById(`${statName}-value`);
        const statBarElement = document.getElementById(`${statName}-bar`);

        statValueElement.textContent = baseStat;
        statBarElement.style.width = `${calculateBarWidth(baseStat)}%`;
        statBarElement.style.backgroundColor = calculateBarColor(baseStat);
      });
    })
    .catch((error) => {
      console.error("Error fetching API data:", error);
    });
};

const searchInput = document.getElementById("pokemon-search");
const datalist = document.getElementById("pokemon-options");

searchInput.addEventListener("input", (event) => {
  const searchText = event.target.value.toLowerCase();
  datalist.innerHTML = "";

  fetch(apiUrl + `?limit=10&offset=0`)
    .then((response) => response.json())
    .then((data) => {
      const pokemonList = data.results.map((pokemon) => pokemon.name);
      const filteredList = pokemonList.filter((pokemon) => pokemon.includes(searchText));

      filteredList.forEach((pokemon) => {
        const option = document.createElement("option");
        option.value = pokemon;
        datalist.appendChild(option);
      });
    })
    .catch((error) => {
      console.error("Error fetching API data:", error);
    });
});

searchInput.addEventListener("change", (event) => {
  const selectedPokemon = event.target.value.toLowerCase();
  updateStats(selectedPokemon);
});

At first I was thinking about having a datalist as an option for users to select what Pokemon they want - hence the datalist const but I later scrapped this as you can't style them as they are browser specific.

##Adjusting the stats table
Okay so we have our JS to allow users to input a Pokemon name and once they do our event listener will change the values of the table.

I also added an event listener to change any input to all lowercase when searching so that it won't be case sensitive when people are searching. 

The next step was the get this table to update in a manner where the bars would be proportional for their value and I wanted for them to be a different colour ranging from a red to green dependent upon if the value was low to high. 

const calculateBarWidth = (value) => (value / 255) * 100;
const calculateBarColour = (value) => {
    console.log("Value:", value);
    if (value >= 120) {
      return "#4eff00"; // Bright Green
    } else if (value >= 100) {
      return "#52ff00"; // Green
    } else if (value === 100) {
      return "#ccff00"; // Yellow
    } else if (value >= 90) {
      return "#ffe400"; // Yellow
    } else if (value >= 80) {
      return "#ffac00"; // Orange
    } else if (value >= 70) {
      return "#ff6600"; // Orange
    } else if (value >= 60) {
      return "#ff4c00"; // Dark Orange
    } else {
      return "#ff0400"; // Red
    }
  }; 

The bar width takes the percentage of the stat where 255 is the max and adjusts the bar to the size based on the percentage.

Calculating the bar colour involved taking that value and then returning a hex value. I trailed using ranges to assign the colour but that had inconsistent results for me. In the future I could simplify this but I wanted a decent range of colours for the different stat values.