The JavaScript built-in Fetch API is awesome. It's a powerful, simple way to send requests and receive responses from a server or your local network. I like it because it's versatile and easy to use.
Let's see how it works by building a simple website. Today, we'll be using the Dog.ceo API to load random images of dogs in the DOM.
Please Note: This tutorial is meant to introduce fellow Newbies looking to explore how the Fetch API works. There is a lot more to Fetch than what you'll read about here, and these examples are by no means exhaustive.
What is an API?
API stands for Application Programming Interface. There are many different types of APIs that do many useful things for us. Here are a few examples of what they can do:
- Browser APIs extend the functionality of your Browser (Chrome, Safari, Brave, etc) to help with visual & local interpretation of code (Client-Side).
- Server APIs extend the functionality of Web Servers, and can manage data for Client-Side requests around the world.
- Web APIs built into your Browser help with sending, receiving, and interpreting data from the Web (Server-Side), such as Third-Party APIs.
- Third-Party APIs allow you to download their code over the Web, once you know where & how to get it. Once you find one you like, read their Docs to learn more.
APIs are particularly useful because they work Asynchronously, meaning they don't run at the same time as other code so they don't hold anything important up, causing annoying delays in page loads or updates.
The fetch() API is one flexible tool that will make your life as a Developer much easier. Fetch allows us to make general definitions for network request & response objects that you can manipulate how you see fit. You could use Fetch for a simple GET request to fetch information (like we are here), or you can include header and body information to make POST, PATCH, or DELETE requests to or from a database.
At the end of the article I've included loads of links for further exploration down the rabbit hole of understanding how to use Fetch, Web APIs, and Asynchronous JavaScript.
Starter Code
If you'd like to follow along, create an "index.html", a "style.css", and an "index.js" file in the text editor of your choice on the same folder-level. We'll be working in our "index.js" file for this example.
Copy and paste this very generic starter HTML & CSS into their respective files. Or, create your own & have fun with it!
<!-- ___index.html___ -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./style.css">
<title>Dog Pictures</title>
</head>
<body>
<h1>Dogs!</h1>
<script src="./index.js"></script>
</body>
</html>
/* ____style.css___ */
body {
background-color: rebeccapurple;
padding-left: 30px;
}
h1 {
color: #fff;
}
img {
max-width: 400px;
}
This is the bare-bones minimum of what you should start with. When we're done, play around with it and make it your own! What matters most is you start with at least a boilerplate HTML structure, and linking your "index.js" file in a <script>
tag at the bottom of the <body>
.
When you open the HTML file in your Browser, it should look something like this:
We're going to be using your Browser's Developer Tools to view the data we're receiving from the Web Server. To open your Dev Tools, right-click your Browser and select Inspect
to reveal the Dev Tools panel.
Select the "Console" tab to view your Console. You can leave this open for now.
Now it's time to write some JavaScript! Go to the blank "index.js" file in your Text Editor, and let's build our generic Fetch function:
/* ___index.js___ */
fetch(apiURL) // Step 1
.then(response => response.json()) // Step 2
.then(data => console.log(data)) // Step 3
.catch(error => console.log(error)); // Step 4
What is this function doing?
STEP 1: FETCH REQUEST FROM AN API's URL
"fetch(apiURL)
"
The Fetch function is a built-in JavaScript function that makes an asynchronous Promise to contact the apiURL we assign to the parameter. This Promise is just an assurance that Fetch will let us know once (or if) a response is received.
Note that there is an option for a second parameter here that would contain metadata, such as the method, header, and body of the request. For a simple GET request like the one we're making, we can omit this and allow for Fetch's default parameters. Check out MDN Web Docs information on Fetch syntax to learn more about making POST, PATCH, or DELETE requests.
STEP 2: HANDLE THE RESPONSE
".then(response => response.json())
"
Once the Fetch's Promise has been kept, meaning the server has received the request, we chain a .then()
method to the Fetch Request to make another Promise. Any time a .then()
method is chained to a Promise, it won't start running until the previous Promise has completed.
Inside this .then()
, we're going to make another Promise to take the response we're receiving, and tell the Fetch function to turn it into a JSON format that we can use.
JSON stands for "JavaScript Object Notation", and is a format commonly used to store data that can be accessed by any code language, not just JavaScript. JSON stores data in a long string, formatted with {}'s storing key:value
pairs inside []'s much like Objects and Arrays, but note that while JSON is similar to JavaScript, it is not JavaScript; it's just a long string. Once we receive our code in JSON format, we can get to the data we need and do things with it.
STEP 3: HANDLE THE DATA
".then(data => console.log(data))
"
Once Step 2's Response Promise has completed, we can now take the information the server sent to us, in JSON format, and do something with it by chaining another .then()
to fetch()
.
The variable data
we're using here is actually the JSON object we got back from the server. You can name it anything you'd like and do what you want with it. For now, we will console.log()
the data we receive so we can look at this JSON object in our console. Once successful, we will be able to do whatever we want with that data, like pass it into a function.
STEP 4: HANDLE THE ERROR (if any)
".catch(error => console.log(error));
"
This is the end of the fetch() function. It's good practice to chain a .catch()
method to the Fetch function, in case there is a problem in any of the previous steps. This works like a .then()
method, but whenever a Promise rejects (fails), whatever happens inside the .catch()
will happen instead.
Note that the Fetch Promise only rejects when a network error happens, not on HTTP errors.
This would be a good place to send an error message to the console so the developer knows about it, or to display a message in the DOM so the User knows to try again later.
Our Request/Response Cycle
Now that we have some background on how a Fetch Request works, let's make our Fetch function work!
At the very top of your "index.js" file, above the fetch function, let's define the apiURL
. Add this line to your code:
const apiURL = 'https://dog.ceo/api/breeds/image/random';
Now, refresh your Browser. The Response Object from the Fetch Request has been received, and if successful, our fetch()
function will now log that Object to your console. If the URL endpoint has a typo, the fetch() request will reject/fail, so make sure it's accurate.
If you have a message in your Console that looks something like this, you're doing great:
Notice the value of "message" in this Response Object is a URL to a .jpg image. To narrow down to the specific information we want, let's change what we're logging to the Console in Step 3 from:
.then(data => console.log(data))
to:
.then(data => console.log(data.message))
Once you've done this, refresh your Browser and check out the Console again.
You should see just the random URL string we received in the Response Object from the Fetch Request in your Console, which is the value of data.message
.
Now that we've singled out the data we want, we're ready to show that image in our DOM!
First, let's make a function that takes a URL as a parameter, and uses that URL parameter to create an image we can display in our DOM.
function showImage(url) {
const image = document.createElement('img');
image.src = url;
image.alt = 'Cute doggo';
document.body.appendChild(image);
}
Great, but now how do we use that function with our Fetch Request?
Pass data.message
to showImage()
Go back to the .then()
line in STEP 3, and change:
.then(data => console.log(data.message))
to:
.then(data => showImage(data.message))
Now, when you refresh your Browser, instead of logging data to your Console, you should see a picture of a cute dog in the DOM.
If a new random image of a dog appears in your DOM every time you reload the page, congratulations. You did it!
Here's the final JavaScript for you:
/* ___index.js___ */
const apiURL = 'https://dog.ceo/api/breeds/image/random';
fetch(apiURL)
.then(response => response.json())
.then(data => showImage(data.message))
.catch(error => console.log(error));
function showImage(url) {
const image = document.createElement('img');
image.src = url;
image.alt = 'Cute doggo';
document.body.appendChild(image);
}
From here you could style the rest of your page, and continue to build this into any website of your imagining.
Now that you know how to use Fetch API, you can use it to communicate with servers, create your own databases, or make a cool web app of your own design.
Try exploring one of the many free public Web APIs on your own to see what you can create by fetching what they have to offer.
Continue Learning
I also highly recommend looking further into why Fetch works on your own. Here are some of the sources I've learned from that helped me in my journey.
The Event Loop:
- "What the heck is the event loop anyway?" | Philip Roberts | JSConf EU
- MDN Web Docs: "Concurrency Model and the Event Loop"
Vital Acronyms:
- Wikipedia: "Representational State Transfer (REST)"
- Wikipedia: "Create, Read, Update, and Delete (CRUD)"
- w3schools: Asynchronous JavaScript and XML (AJAX)
- Wikipedia: "JavaScript Object Notation (JSON)"
- MDN Web Docs: Hypertext Transfer Protocol (HTTP)
Tools and Resources:
- JSONLint- The JSON Validator app
- Google Chrome Web Store: JSON Formatter Extension
- REST API Tutorial: HTTP Methods
More about Fetch
Thanks for reading, and happy coding!
Top comments (0)