Detailed Explanation: pokePicker project using JS x API

projectnick
7 min readJan 18, 2023

check out the full project here: https://github.com/nick-is-coding/PokeAPI-project

Alrighty, as I am working through my Web Development bootcamp, I have finally approached the last JavaScript module! It wraps up nicely with a project that has you create a website using HTML, CSS, JS and a call to some API of your choosing.

In this article, I will be mainly talking about the JavaScript and not so much the HTML and CSS used on this project. I will walk through how I built this project to not only solidify my own knowledge, but to also give you some insight on the how and why behind each function I used within JS, and a couple obstacles I ran into along the way.

Let’s get into this!

PRE-PLANNING — I used the first two methods of the Puzzle Method to approach this project.

PRE-PLANNING

What should this do? What should it look like?

  • HTML, CSS, JS and an API call
  • JS should create HTML using data from chosen API (30 items)
  • Favorites tab to store your favorite
  • Ability to sort the objects in the collection and favorites
  • Should display some data that is pulled from API

Dump it out — JS

  • Set up main.js and favorites.js file
  • Create variables to store: API URL, card container, and favorites container
  • Create functions to: grab URL of random pokemon via API data, store the pokemon data needed from the URL and push to card container, generate and implement HTML card using data retrieved from card container, button to add card to favorites, sort function

To begin, I needed to choose an API (Application Programming Interface). I wanted this project to be fun and engaging to work on so I picked the pokeAPI which holds a bunch of data about a specific Pokemon (name, type, attack stats, hp, etc.)

To refresh my memory on how API calls worked, I watched this video.

FUNCTIONS WITHIN main.js EXPLAINED

catchPokemon()

  • Loops and updates the counter until it hits 30 via while loop
  • Creates a finalURL using both the stored Pokemon API URL (declared outside the function) + a random number stored in an “id” variable
  • Fetches the random Pokemon using the finalURL
  • Returns the data grabbed from API and parses it as json
  • Passes the data to the storePokemon() function so that it can access the data

storedPokemon()

  • Uses data passed from catchPokemon()
  • Creates an object called “caughtPokemon” to store variables
  • Variables within object store the specific data needed (name, ID, image, type, hp, attack) pulled from the API
  • Pushes the object to the “pokeStorage” which will be an empty array that will contain each caughtPokemon
  • Then will pass the caughtPokemon object to the generateCard() function so the card can be created using the newly caughtPokemon’s data

generateCard()

  • Takes a parameter called “poke”
  • Grabs the “original-container” and uses .insertAdjacentHTML so that it can push the newly created HTML before the “original-container” ends
  • Html then uses string literals to access information from the poke (which poke.pokeID would be replaced to caughtPokemon.pokeID)
  • Calls buttonFunctionality(); and passes the poke paramater so it can access the data used
  • Updates num++ after each card is created

buttonFunctionality()

  • Takes “poke” as a parameter
  • Grabs each unique moveButton/blockToMove by using document.getElementByID to grab element and then uses pokeStorage[num].pokeID to gran uniquely created card
  • Declare addText and removeText variables to update button once it is pressed with different text
  • Set state of card to ‘not favorite’ so that when the button is pressed, we can change the state of the card to ‘favorite’
  • Created a moveButton event listener
  • If card state is “not-favorite” upon being clicked, then add data attribute of favorite, change text content to “removeText”, append the card that the moveButton in which it is attached and append it to the favorite’s container, cardState is equal to favorite, push the favorited pokemon’s data to the favoriteStorage, splice/remove that Pokemon’s data from the pokeStorage, update the sum of the “total HP of team” & “total attack of team” with the current Pokemon’s hp and attack pts, update those using totalStats()
  • Else card state is favorite upon being clicked, then remove favorite attribute, change button’s text content to “addText”, append the card being unfavorited to the originalContainer, change card-state to “not-favorite”, push that Pokemon’s data to the pokeStorage, splice out the Pokemon’s data from the favorites collection, update total sum and attack pts of team within favorites collection, call totalStats() to update those stats

totalStats()

  • update’s text content of sum / attack with the new sum / attack variable from the updated buttonFunctionality();

runSort()

  • Function used to sort the cards from A-Z or Z-A
  • Sets num counter to 0
  • Runs a sort function that takes each Pokemon (pokeA, pokeB) and stores the name of both within the nameA/nameB variables (also makes them both lowercase)
  • When comparing the two Pokemon, it checks if the nameA is less than nameB, and if so, it returns -1, indicating that pokeA should come before pokeB in the sorted array.
  • If nameA is greater than nameB, it returns 1, indicating that pokeB should come before pokeA in the sorted array
  • If nameA and nameB are equal, it returns 0, indicating that pokeA and pokeB should be considered equal and their order doesn’t matter
  • isAscending = !isAscending sets isAscending to the opposite so that next time it is ran, it will do it in the reverse order
  • Depending on if it isAscending or not, will determine what the text is (a-z or z-a) of the sort button
  • Then the “forEach” method iterates over the sorted “favoriteStorage” array, and for each element in the array, it gets the corresponding card element from the HTML by its unique id, updates the poke-name element text content, and appends the card to the “favoriteContainer” element

Obstacles I ran into

How to EFFICIENTLY set up the unique cards by ID

This was one of my biggest obstacles. When I was adding string literals to input the newly parsed data from the API, instead of using this:

<div id=”blockToMove-${poke.pokeID}” class=”container”>

I used

<div id=”blockToMove-${pokeStorage[num].pokeID}” class=”container”>

The way I had set up the functions, I was not passing the data directly to the generateCard function, but rather, grabbing the data that had been recently pushed to the pokeStorage and using a num counter outside the function to increase after each card was generated so that the num inside the literal would increase by 1 with each Pokemon, giving it’s unique ID… it worked at first, but when it got to the sorting function, I ran into a HUGE problem. The ID was attached to the num counter, so whenever it was repopulating, it was confusing the [num] and just ended up not working whatsoever.

To fix the issue, I had to kind of rearchitect how the functions worked. Once I ran the storePokemon(), I passed the caughtPokemon to the generateCard( ) and then changed the syntax of the string literal. This made my life a million times easier.

Breaking the complex functions into smaller functions:

Originally, I had the catchPokemon() and storePokemon() function bundles into one function. However, I remember in my bootcamp that they taught me to always try and segment the large functions into smaller functions that call upon other functions within that function… that was a mouthful haha. But yeah, it helps a lot for a couple of reasons:

  • If you have issues, it’s easier to troubleshoot a bunch of small functions one at a time to get to the culprit instead of trying to read through a large complex function
  • Large complex functions are hard to read through and understand
  • It makes your code look cleaner

All in all, if you are wanting a solid project to push your knowledge forward, grab a cool looking API and create a website using the data you pull from it. It’s a fun, challenging, and rewarding project for sure.

If you have any additional questions, hit me up! If you want to follow my GitHub and/or check out the full project… here ya go!

Until next time… PEACE!

--

--

projectnick

Software Developer || Creative || EX-Tech Recruiter/AM