DEV Community

Cover image for How to Populate HTML Dynamically with Data from An API
Ethan Groene
Ethan Groene

Posted on • Originally published at javascript.plainenglish.io

How to Populate HTML Dynamically with Data from An API

As a web developer (and as a software developer in general), it is of utmost importance that you learn how to work with Application Programming Interfaces (APIs). To explain briefly, an API is a collection of data that you can access by using the fetch() method in JavaScript. Instead of all that data being stored locally, it’s stored on another server somewhere & you can access all or part of the data when you need to. You will need to display that data on a certain part of your website or application & at a certain time.

In the example I write about here, I will walk you through how I fetched data from an API containing info on Harry Potter characters to how I displayed that data on the page. Little did I know, retrieving the API data & displaying it would actually be one of the easiest parts of the project, but that’s a story for another day if I ever feel inclined to write about that. Enough babble, let’s get started.


Fetch API Data

First, let’s assign the part of the HTML document (chars-container) to a variable, which will eventually be populated with the character information we fetch from the API:

const charsSection = document.getElementById('chars-container');
Enter fullscreen mode Exit fullscreen mode

Then, let’s assign the URL of the API to a variable (makes the code much neater when we fetch the API data) & create an asynchronous function, since we need to await the retrieval of data from the API):

// Assign API URL to variable:
const charsURL = 'https://hp-api.herokuapp.com/api/characters';

// Function to return array of filtered character data objects from API:
async function getChars() {
    // Fetch API data:
    const response = await fetch(charsURL);

    // Convert API data to JSON:
    const allCharsArr = await response.json();

    // Push into iterable array, newCharsArr, all characters that are human & contain an image URL:
    let newCharsArr = [];
    for (let i = 0; i < allCharsArr.length; i++) {
        if (allCharsArr[i].species === 'human' && allCharsArr[i].image.length > 0) {
            newCharsArr.push(allCharsArr[i]);
        }
    }
    return newCharsArr;
}
Enter fullscreen mode Exit fullscreen mode

This function, getChars(), fetches the API data, converts that data to JavaScript Object Notation (JSON), then pushes each data object into a new, iterable array, newCharsArr, as long as the object’s .image property length was greater than 0 (all of the .image properties in the API that were not empty contained a valid image URL) & as long as the object’s .species property is equal to ‘human’.

You may want to filter the API data for several reasons, one of which may that the API is incomplete, as is the case here. You can normally get around this issue if you know how to manipulate data in JS objects with loops, conditional statements, etc., as long as it satisfies your project requirements or until the API is complete. In this case, not every character data object in the API contained an image, & this was necessary for the project, so I filtered out data objects that didn’t contain an image.

So, the getChars() function above returns an iterable array containing data objects from the API whose .species property is ‘human’ & whose .image property length is greater than 0.

Populate the Page with Retrieved API Data

async function buildPage() {
    const newCharsArr = await getChars();
    // Populate character cards' HTML:
    for (let i = 0; i < newCharsArr.length; i++) {
        // Populate homepage (make cards visible by default)
        charsSection.innerHTML += 
            "<div class='char-card' data-name='" + newCharsArr[i].name.toLowerCase().replace(/\s/g, '-') + "' data-house='"
            + newCharsArr[i].house.toLowerCase().replace(/\s/g, '-') + "'>" 
                + "<div class='char-img-container'>"
                + "<button class='favs-btn' title='Add to Favorites'><i class='far fa-heart'></i></button>"
                + "<img src='" + newCharsArr[i].image + "'>"
                + "</div>"
                + "<header class='char-header'>" + newCharsArr[i].name + "</header>"
                + "<p><span>Ancestry: </span>" + newCharsArr[i].ancestry + "</p>"
                + "<p id='house-homepage'><span>House: </span>" + newCharsArr[i].house + "</p>"
                + "<p><span>Actor/Actress: </span>" + newCharsArr[i].actor + "</p>"
            + "</div>"
    }
}
Enter fullscreen mode Exit fullscreen mode

Remember the charsSection variable we declared at the beginning? The function above, buildPage() , populates that with the filtered data objects we retrieved with the getChars() function. Since getChars() was asynchronous & had to await the retrieval of data from the API, buildPage() must also be asynchronous & await the calling of getChars() before it can populate the innerHTML of charsSection.

I assigned the iterable array of filtered data objects to newCharsArr in buildPage() above. For every item in newCharsArr`, we dynamically create a card containing select information (character’s image, name, ancestry, Hogwarts house, & actor/actress) about the character which that item represents.


Here’s an excerpt of the page once the characters’ information is fetched, filtered, and the page is populated with it. I did not include any info about the styling, but if you’d like to see my code for the entire project, go here.

Image description


So there you have it, a brief example of how to dynamically populate a webpage with information fetched from an API. If you have any comments or questions, I’d be happy to respond. If you found this article helpful, I’d appreciate a nice comment or a clap or two, so I can know what content my readers like. If you think others would find this useful, please share it with them.

Thanks for reading!

Links

Project in action

Project repo

MDN Web Docs ‘Introduction to Web APIs’

Originally published to Medium for JavaScript in Plain English on November 14, 2022

Top comments (0)