Lesson 20 of 33
Fetching Data from the Web
Connect your JavaScript to real servers using fetch(), async/await, JSON parsing, HTTP methods, status codes, and network error handling.
When you visit a weather website, check a live sports score, or send a message in a chat app, how does the web page get fresh information without reloading the whole screen?
The answer is fetching data from APIs.
JavaScript includes a built-in function called fetch() that acts like a messenger. It sends a message over the internet to a server, waits for the server to reply, and brings back fresh data for your page to display.
- Step 1
1. Call fetch(url)
Sends an HTTP request across the internet to the server
- Step 2
2. Receive Response
Server returns headers and status code (e.g., 200 OK)
- Step 3
3. await response.json()
Reads and converts raw JSON text into a live JS object
- Step 4
4. Update UI
Renders fresh data on screen without reloading the page
The anatomy of an HTTP request
When your browser talks to a server, it uses HTTP (HyperText Transfer Protocol). Every request is made up of a method, a URL, a set of headers and sometimes a body. The request specifies a method, which tells the server what you want to do:
GET Method
Retrieve data from the server (read-only, default for fetch).
POST Method
Send new data to the server to create something (e.g. submitting a comment).
PUT / PATCH Methods
Update or modify an existing resource on the server.
DELETE Method
Remove a resource from the server.
Your first fetch request
fetch() uses Promises under the hood, so it works naturally with async and await:
async function loadUserData() {
try {
// 1. Send request over the network
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
// 2. Check if the server responded successfully (status 200-299)
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
// 3. Parse the incoming JSON text into a JavaScript object
const user = await response.json();
console.log("User Name:", user.name);
console.log("User Email:", user.email);
} catch (error) {
console.log("Failed to fetch user:", error.message);
}
}
loadUserData();Let us step through what happened:
fetch(...)starts the network call and returns a response promise.response.okistrueif the HTTP status code is between 200 and 299.response.json()reads the response body stream and converts the raw text into a real JavaScript object.
Sending data with POST
To send data (like submitting a form or posting a comment), pass an options object as the second argument to fetch():
async function createNewPost() {
const newPostData = {
title: "Learning JavaScript",
body: "This post was sent from the browser with fetch().",
userId: 1,
};
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(newPostData), // Convert object to JSON string
});
if (!response.ok) {
throw new Error("Server rejected post creation");
}
const createdPost = await response.json();
console.log("Created successfully with ID:", createdPost.id);
} catch (err) {
console.log("Post failed:", err.message);
}
}Notice JSON.stringify(newPostData). Over the network, servers speak raw text, not live JavaScript objects. JSON.stringify() serialises our object into a string, and Content-Type: application/json tells the server how to read it.
Try it yourself
This makes a real network request against a free mock API (jsonplaceholder.typicode.com). Change the id in the URL to something invalid like 9999 and watch the error path run.
Common pitfalls
- Forgetting
awaiton.json():response.json()returns a Promise. If you omitawait, the variable holds a still-pending Promise rather than your data, and logging it printsPromise { <pending> }. - Assuming
fetchrejects on 404: A 404 Page Not Found is a successful network response returning a 404 status. Always checkresponse.ok. - Handling Offline Users: Always wrap
fetch()intry...catch. If a user loses Wi-Fi connection,fetch()will throw aTypeError: Failed to fetch. - Showing Loading States: Before calling
fetch(), set a loading spinner or text (loading = true). When done (insidefinally), turn it off (loading = false).
What to remember
fetch() connects browser JavaScript to web servers. Use await fetch(url) to send a request, check response.ok before trusting the result, parse the body with await response.json(), send data with POST and JSON.stringify(), and wrap the whole thing in try...catch for the times the request never arrives.
Check yourself
4 questions · pass 3/4 to unlock Scope and Closures
1.What does the fetch() function return?
2.Why must you call await response.json() after fetch()?
3.Does fetch() reject its Promise when a server returns a 404 or 500 status code?
4.What HTTP method should you use when sending new data to be created on a server?
4 left to answer