Fetching data from somewhere else
So far all the data in your code has been typed by you. But much of the web is built on data that lives somewhere else: weather forecasts, exchange rates, news, a list of your GitHub repositories. In this lesson you'll learn to load data from the internet with JavaScript.
What an API is
An API is a way for programs to talk to each other. Many websites offer APIs that give out data in JSON format when you visit a special address, called an endpoint.
Try it right now. Open this address in your browser:
https://api.github.com/users/octocat
Instead of a web page, you get JSON with information about GitHub's mascot account. That's an API endpoint. Your code can ask for the same data and use it on your page.
fetch
JavaScript has a built-in function for requesting data, called fetch:
fetch('https://api.github.com/users/octocat');There's a twist. Asking a server for data takes time, maybe a tenth of a second, maybe several seconds on a slow connection. JavaScript doesn't stop and wait. It carries on with the rest of your code and deals with the answer when it arrives. This is called asynchronous code.
async and await
The easiest way to work with asynchronous code is with async and await:
async function loadProfile() {
const response = await fetch('https://api.github.com/users/octocat');
const data = await response.json();
console.log(data.name);
}
loadProfile();Here's what happens:
asyncin front of the function means it contains code that waitsawait fetch(...)sends the request and waits for the responseawait response.json()waits for the body of the response and turns the JSON into a JavaScript object- Now
datais a normal object, anddata.nameis the account's name
await only works inside an async function. And it's the reason the code reads top to bottom like everything else you've written, even though there's waiting involved.
What does await do?
Select one answer
Showing the data on your page
Combine fetch with what you learned about the DOM:
<section id="github"> <h2>My GitHub</h2> <p id="repo-count">Loading...</p> </section>
async function showRepoCount() {
const response = await fetch('https://api.github.com/users/your-username');
const data = await response.json();
const repoCount = document.querySelector('#repo-count');
repoCount.textContent = `I have ${data.public_repos} public repositories on GitHub.`;
}
showRepoCount();Replace your-username with your own GitHub username. The paragraph shows "Loading..." for a moment, then updates with the real number. Showing a loading message is a nice touch, because visitors can tell something is happening.
When things go wrong
Networks fail. Servers go down, people lose their connection and addresses get typos. Good code handles that instead of breaking silently.
First, check that the server actually said yes. response.ok is true when the request succeeded:
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}throw creates an error on purpose. Then wrap everything in try and catch, which catches errors so you can deal with them:
async function showRepoCount() {
const repoCount = document.querySelector('#repo-count');
try {
const response = await fetch('https://api.github.com/users/your-username');
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
const data = await response.json();
repoCount.textContent = `I have ${data.public_repos} public repositories on GitHub.`;
} catch (error) {
console.error(error);
repoCount.textContent = "Couldn't load my GitHub stats right now.";
}
}If anything inside try fails, JavaScript jumps straight to catch. The visitor sees a friendly message instead of "Loading..." forever, and you see the real error in the console.
What is the catch block for?
Select one answer
A few practical notes
- Public APIs have limits. GitHub's API allows a limited number of requests per hour without signing in. That's plenty for a personal page, but don't call it in a loop.
- Never put secret keys in front end code. Some APIs need a key. Anything in your JavaScript files can be read by anyone with the Inspect tool, so keys that cost money or give access to accounts must live on a server instead. The APIs in this lesson don't need keys.
- The data's shape is in the docs. Open the endpoint in your browser first to see what the JSON looks like, then pick the properties you need.
An API needs a secret key that's tied to your paid account. Where should it go?
Select one answer
Load real data onto your website:
- Open
https://api.github.com/users/your-usernamein your browser with your own username and look at the JSON - Add a "My GitHub" section to your page with a "Loading..." paragraph
- Write an
asyncfunction that fetches your profile and shows your number of public repositories - Add
tryandcatchwith a friendly error message - Test the error handling by misspelling the address on purpose, then fix it
Commit and push. Your live site now loads real data from the internet.