AJAX Part 4: Loading Data From An External API

Welcome to the fourth and final article in this series all about AJAX. If you haven't read the other three guides I recommend starting with AJAX Part 1: What is AJAX?.

In the previous article we discovered how to load JSON data from a local server using AJAX. In this instalment, we'll explore a more practical example where we'll fetch JSON data from an external API.

In this case, we'll use the GitHub API to load a list of GitHub users.

Just a reminder that throughout this series I'm using Visual Studio Code as my text editor. It has a handy feature called 'Live Server' that we'll be using to serve up the demo application.

HTML

Once again, let's get started with the HTML. Similar to the previous guide, we'll need a button with an event listener to trigger the request. This time we can call the file something like ajax-external-json.html, with the following content:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AJAX 3 - External API</title>
    <style></style>
  </head>
  <body>
    <button id="button">Load GitHub users</button>
    <br /><br />
    <h2>GitHub Users</h2>
    <div id="users"></div>
  </body>
</html>

Once again, feel free to add a title to distinguish this file from previous work. In this above example I've labelled the document 'AJAX 3 - External API', as this is the third demo app that we'll be building.

Note that we have a button that will eventually trigger the AJAX request, as well as a <div> with the ID users that will be used to display the returned user data.

Adding the event listener

Let's create a <script> tag and add the event listener and set the callback to a function called loadUsers:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AJAX 3 - External API</title>
    <style></style>
  </head>
  <body>
    <button id="button">Load GitHub users</button>
    <br /><br />
    <h2>GitHub Users</h2>
    <div id="users"></div>
    <script>
      document.getElementById("button").addEventListener("click", loadUsers);

      function loadUsers() {}
    </script>
  </body>
</html>

Stub out loadUsers

We can also initialise the XMLHttpRequest object and open a GET request to the GitHub API endpoint:

function loadUsers() {
  const xhr = new XMLHttpRequest();
  xhr.open("GET", "https://api.github.com/users", true);
}

While we're here, let's stub out the rest of the function:

function loadUsers() {
  const xhr = new XMLHttpRequest();
  xhr.open("GET", "https://api.github.com/users", true);

  xhr.onload = function() {};

  xhr.onerror = function() {
    console.error("Request error");
  };

  xhr.send();
}

onload logic

The main business logic will all be handled in the onload callback. Here we'll need to:

  • Parse the returned JSON response as text.
  • Initialise an empty userInfo variable that will hold all of the user information.
  • Loop through the returned user data and build up a <div> that will display the user's avatar image, ID and username.
  • Set the innerHTML of the users <div> to be the content of the userInfo variable.

We'll focus solely on the onload callback for clarity. First let's check the HTTP status, parse the response JSON and initialise the userInfo variable:

xhr.onload = function() {
  if (this.status == 200) {
    const users = JSON.parse(this.responseText);

    let userInfo = ``;
  }
};

Notice that I've used backticks for the userInfo string as we'll be building this up using template strings.

Building up userInfo

Now let's use a for loop to iterate through each of the returned GitHub user profiles and build up the template string with their information.

This will include a containing <div> for each user, an <img> to display their profile image, and a <ul> to list the user's ID and username.

let userInfo = ``;

for (let i = 0; i < users.length; i++) {
  userInfo += `<div class="user">
        <img src="${users[i].avatar_url}" width="70" height="70">
      <ul>
          <li>ID: ${users[i].id}</li>
        <li>Login: ${users[i].login}</li>
      </ul>
      </div>`;
}

Finally, we just need to grab the <div> with ID users and set the innerHTML content equal to that of the userInfo variable:

document.getElementById("users").innerHTML = userInfo;

Take care to note that this is performed outside of the loop!

Check your work

Here's the full code for comparison, including the HTML and JavaScript. I've also added a little CSS to the <head> to help visually separate each user:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>AJAX 3 - External API</title>
    <style>
      .user {
        display: flex;
        background: lightblue;
        padding: 10px;
        margin-bottom: 10px;
      }

      .user ul {
        list-style: none;
      }
    </style>
  </head>
  <body>
    <button id="button">Load GitHub users</button>
    <br /><br />
    <h2>GitHub Users</h2>
    <div id="users"></div>
    <script>
      document.getElementById("button").addEventListener("click", loadUsers);

      function loadUsers() {
        const xhr = new XMLHttpRequest();
        xhr.open("GET", "https://api.github.com/users", true);

        xhr.onload = function() {
          if (this.status == 200) {
            const users = JSON.parse(this.responseText);
            let userInfo = ``;

            for (let i = 0; i < users.length; i++) {
              userInfo += `<div class="user">
                                <img src="${users[i].avatar_url}" width="70" height="70">
                              <ul>
                                  <li>ID: ${users[i].id}</li>
                                <li>Login: ${users[i].login}</li>
                              </ul>
                              </div>`;
            }

            document.getElementById("users").innerHTML = userInfo;
          }
        };

        xhr.onerror = function() {
          console.error("Request error");
        };

        xhr.send();
      }
    </script>
  </body>
</html>

Testing the app

To start up the code and test things out, right-click anywhere in the file and select 'Open with Live Server'. The app should open in your default browser.

Click the 'Load GitHub users' button to see if the users are being loaded from the GitHub API successfully. If everything has gone to plan you should see something like this:

GitHub users displayed

If nothing seems to happen, check the developer console in your browser to see if any errors have been logged. Go back over the code line by line and check that everything is in place correctly.

When you're finished, remember to right-click the HTML file once more and select 'Stop Live Server' to shut the server down.

Conclusion

Congratulations! You made it to the end of this series on AJAX and built three demo applications to demonstrate various ways of working with it. Hopefully this has painted a clearer picture of the benefits of AJAX and inspired some ideas about how to use it in your own projects going forward.

If you're still unclear on any of the theory behind AJAX, be sure to head back to the first article in the series AJAX Part 1: What is AJAX? to have another read. Asynchronous JavaScript can seem pretty strange at first, so don't worry if it takes a while for these concepts to settle in.

Next steps

AJAX can have many uses and solve all sorts of problems. One major implementation is in submitting form information for a smoother user experience.

This is quite a large topic and is unfortunately out of the scope of this series. For details on how AJAX works with forms, check out the MDN documentation.