June 18, 2020 5 min read

Understanding Async / Await in JavaScript ES6

In this article, I’ll attempt to explain the async/await syntax by diving into what it is and how it works behind the scenes while having fun with the Star Wars API.

Let's get started

First, let's discuss the basics of async / await. To make an asynchronous function you must add the async keyword in front of the function. This allows the function the capability to know there may be an await keyword being used to invoke the call and to return a promise rather than directly returning a value. Second, await can be put in front of any async promise-based function to pause your code on that line until the promise fulfills, then return the resulting value. In the meantime, other code that may be waiting for a chance to execute gets to do so.

The Beginning

From my experience, one of the best ways to get a good understanding on how a method works is to dive straight in the code and mess around with it. With that said, I'm going to create a dropdown list that will populate all the star wars characters that the Star Wars API provides for me. When I select a character from the dropdown list I then want to populate the details provided for that character underneath. So, The first thing we want to do is set up a few variables to get us started.

// star wars endpoint
const apiBaseURL = "https://swapi.dev/api/";
// characters dropdown
const characters = document.querySelector(".characters");
// wrapping div
const wrap = document.createElement("div");
// default count
let count = 1;

Fetch Data

Next, let's create our first async function called setCharacters. We want this function to fetch all characters from the endpoint provided from the API and to populate the characters dropdown right after the page loads.

// builds dropdown
const setCharacters = async () => {
// fetch characters & store object
const response = await fetch(`${apiBaseURL}people/`);
const data = await response.json();
// add blank as default option
characters.add(new Option("Select a Name", ""));
// if results, map and build options
data && data.results.map((elt) => {
    const {name} = elt;
    const option = document.createElement("option");
    option.value = count++;
    option.innerText = name;
    characters.appendChild(option);
  });
}

Show Details

Now that we have the dropdown populated with characters. We need to create another async function that will display their details once selected.

getPlanet Async Function
// gets details for specific planet
const getPlanet = async (id) => { 
    // fetch details, store and return object
    const response = await fetch(`${apiBaseURL}planets/${id}`);
    const data = await response.json();
    return data;
}
setDetails Async Function
// display character details
const setDetails = async (id) => {
    // fetch details & store object
    const response = await fetch(`${apiBaseURL}people/${id}`);
    const data = await response.json();
    // destruct what we want 
    const { name, height, mass, hair_color, skin_color, eye_color, birth_year, gender, homeworld } = data;
    const planet = await getPlanet(homeworld.slice(-2));
    // build UI
    wrap.innerHTML = <>`<ul class="list-group list-group-flush">
        <li class="list-group-item"><b>Full Name</b>: ${name}</li>
        <li class="list-group-item"><b>Height</b>: ${height}</li>
        <li class="list-group-item"><b>Mass</b>: ${mass}</li>
        <li class="list-group-item"><b>Hair Color</b>: ${hair_color}</li>
        <li class="list-group-item"><b>Skin Color</b>: ${skin_color}</li>
        <li class="list-group-item"><b>Eye Color</b>: ${eye_color}</li>
        <li class="list-group-item"><b>Birth Year</b>: ${birth_year}</li>
        <li class="list-group-item"><b>Gender</b>: ${gender}</li>
        <li class="list-group-item"><b>Home World</b>: ${planet.name} - Population ${planet.residents.length}</li></ul>`</>;
    // display UI
    characters.after(wrap);
} 

Wrapping it up

Okay, we now have two functions. One to populate our dropdown with the Star Wars characters and one function to display their details once selected. All that's left is to add an event listener for the setDetails function to run when the dropdown value changes.

Add Change Event
characters.addEventListener("change", (e) => {
    // set id from selected value
    const id = e.currentTarget.options[e.currentTarget.selectedIndex].value;
    // clear previous
    wrap.innerText = " ";
    // build UI
   setDetails(id ? id : '');
}, false);
Init Function on Load
setCharacters();

Complete Code

You can find a working example here: https://codepen.io/decodesalot/pen/jOPBeBN