From One Junior to Another: How Pokémon Helped Me Finally Understand Async JavaScript

Abigeal AfolabiAbigeal Afolabi
4 min read

Hey fellow code strugglers! 👋

I won't pretend I'm some senior developer with years of experience. I'm a junior developer just like many of you, and I want to share how, after weeks of frustration, I finally understood one of JavaScript's most confusing concepts.

The Struggle Is Real

Let me tell you about my typical day just two months ago:

  1. Find tutorial on fetching API data ✅

  2. Copy the code exactly ✅

  3. Run the code ✅

  4. Get a blank screen or "undefined" errors ✅

  5. Question my career choices ✅

Sound familiar? My biggest problem was understanding why my data wasn't showing up when I needed it. I'd write code like this:

function getBadPokemon() {
  let pokemonData;
  fetch('https://pokeapi.co/api/v2/pokemon/pikachu')
    .then(response => response.json())
    .then(data => {
      pokemonData = data;
    });

  console.log(pokemonData); // Always undefined!
  return pokemonData; // Always returned undefined!
}

And then wonder why pokemonData was always undefined. I read about "asynchronous" code but couldn't wrap my head around it until I built this Pokémon project from scratch.

The Project That Changed Everything

After my 5th failed attempt at getting API data to work, I decided to start super simple with something fun - Pokémon! Here's how I structured my beginner project:

pokemon-learner/
├── src/
│   ├── pokemonFetcher.js    # The magical file that changed everything
│   └── index.js             # Super simple starting point
└── package.json

The Magical File That Made It Click

Here's the code that finally helped everything make sense:

// src/pokemonFetcher.js

// The "async" keyword was the first key insight!
const fetchPokemonDetails = async (pokemonName) => {
  try {
    console.log(`Looking for ${pokemonName}...`);

    // The "await" keyword was the second key insight!
    const response = await fetch(`https://pokeapi.co/api/v2/pokemon/${pokemonName.toLowerCase()}`);

    if (!response.ok) {
      throw new Error(`Couldn't find ${pokemonName}!`);
    }

    // Another "await" - this was the third key insight!
    const data = await response.json();

    // Now I have actual data to work with!
    return {
      name: data.name,
      id: data.id,
      types: data.types.map(type => type.type.name),
      sprite: data.sprites.front_default
    };
  } catch (error) {
    console.error(`Error: ${error.message}`);
    return null;
  }
};

module.exports = { fetchPokemonDetails };

What Made It Finally Click For Me

After staring at this code for hours, I realized three key things:

  1. The async keyword tells JavaScript "this function will have waiting periods"

  2. The await keyword tells JavaScript "pause right here until this finishes"

  3. The try/catch block handles errors when things inevitably go wrong

But the BIGGEST realization was understanding that JavaScript doesn't wait around naturally. Code executes line by line without waiting for operations to complete unless you specifically tell it to with await.

How I Use This In My Main File

Once I understood the fetcher, using it became simple:

// src/index.js
const { fetchPokemonDetails } = require('./pokemonFetcher');

// Another async function!
const main = async () => {
  console.log('Starting Pokémon search...');

  // The await here ensures we get the actual Pokémon data
  const pikachu = await fetchPokemonDetails('pikachu');

  if (pikachu) {
    console.log(`Found ${pikachu.name}!`);
    console.log(`Types: ${pikachu.types.join(', ')}`);
    console.log(`Check out their picture: ${pikachu.sprite}`);
  }
};

// This catches any unhandled errors in our main function
main().catch(error => {
  console.error('Something went wrong:', error);
});

The Analogy That Helped My Brain

As someone new to coding, technical explanations weren't helping me. What finally made sense was thinking about it like texting a friend:

When you text someone, you don't freeze in place waiting for them to respond. You send the text and go about your day until you get a notification they replied. That's how async JavaScript works!

  • Sending the text = making the API call

  • Going about your day = JavaScript continuing to run other code

  • Getting a notification = the Promise resolving

  • Reading their response = working with the data

My Top 5 Beginner Mistakes (So You Can Avoid Them)

  1. Forgetting the async keyword on functions where I used await

  2. Not using await when working with the result of an async function

  3. Trying to access data outside the async function before it was ready

  4. Not using try/catch blocks (errors would crash my entire app)

  5. Console.logging after starting an async operation but before it completed

Try It Yourself!

The only way I truly understood this was by building something myself. Try this:

  1. Create the two files above

  2. Run npm init -y to create a package.json

  3. Run node src/index.js

  4. Change the Pokémon name to your favorite and see what happens!

What's Next On My Learning Journey

Now that I understand the basics of async/await, I'm working on:

  1. Fetching multiple Pokémon at once with Promise.all()

  2. Building a simple web UI to display the Pokémon

  3. Adding error handling for when the API is down

  4. Creating a simple storage system so I don't have to re-fetch Pokémon

Let's Learn Together!

I'm still learning every day, and I'd love to hear your experiences. What JavaScript concepts have you struggled with? What finally made them click for you?

Drop a comment below or connect with me here on Hashnode. We juniors need to stick together! 💪

Happy coding, and remember – every senior developer was once confused by async/await too!


PS: If you spot any mistakes in my explanations, please let me know gently in the comments. I'm still learning!

13
Subscribe to my newsletter

Read articles from Abigeal Afolabi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abigeal Afolabi
Abigeal Afolabi

🚀 Software Engineer by day, SRE magician by night! ✨ Tech enthusiast with an insatiable curiosity for data. 📝 Harvard CS50 Undergrad igniting my passion for code. Currently delving into the MERN stack – because who doesn't love crafting seamless experiences from front to back? Join me on this exhilarating journey of embracing technology, penning insightful tech chronicles, and unraveling the mysteries of data! 🔍🔧 Let's build, let's write, let's explore – all aboard the tech express! 🚂🌟 #CodeAndCuriosity