JavaScript
Connect your web app to real-world servers using fetch, JSON parsing, HTTP methods, and clean error handling.
1. What is the Fetch API?
In simple words, fetch() is JavaScript's built-in phone line to the internet. Whenever your app needs to load products from a database, save user settings, or check the live weather, you use fetch() to send a request to a server and get data back.
Think of fetch() like ordering food in a restaurant:
- Step 1 (The Waiter Arrives):
const response = await fetch(url)
The waiter comes back to your table with a covered tray. You inspect the bill to see if the order succeeded (response.ok === true). - Step 2 (Uncovering the Food):
const data = await response.json()
You lift the tray cover to unpack and eat the actual food (the JSON data).
2. The Two-Step Fetch Blueprint
Because network data arrives in chunks (streams), Fetch always requires two await steps: first getting the response envelope, and then parsing the JSON body.
async function getUserProfile() {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
if (!response.ok) {
throw new Error(`Server returned status: ${response.status}`);
}
const user = await response.json();
console.log("✅ User Name:", user.name);
console.log("📧 Email:", user.email);
console.log("🏙️ City:", user.address.city);
} catch (err) {
console.error("❌ Failed to fetch user:", err.message);
}
}
getUserProfile();
✅ User Name: Leanne Graham 📧 Email: Sincere@april.biz 🏙️ City: Gwenborough
3. The #1 Fetch Interview Trap: response.ok
This is asked in almost every frontend interview: fetch() does NOT fail on 404 (Not Found) or 500 (Server Error)!
As long as the browser was able to contact the server, the Promise resolves successfully. It only rejects if the user has no internet connection, DNS fails, or CORS blocks it.
response.ok
A boolean: true for HTTP 200–299; false for 404, 500, 401.
response.status
The exact numerical HTTP code (e.g., 200, 201, 404, 500).
response.json()
An async method returning a Promise that parses incoming JSON.
4. Sending Data with POST Requests
When creating new data (like registering an account or posting a tweet), pass an options object with method: "POST", the Content-Type header, and serialize your JavaScript object with JSON.stringify().
async function createNewPost(title, text) {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title, body: text, userId: 101 })
});
if (!response.ok) {
throw new Error(`Failed to create post. Status: ${response.status}`);
}
const newPost = await response.json();
console.log("🎉 Post Created! Assigned ID:", newPost.id);
console.log("📝 Title:", newPost.title);
} catch (error) {
console.error("Error creating post:", error.message);
}
}
createNewPost("Mastering JavaScript", "Fetch API is simple when you understand the 2 steps!");
🎉 Post Created Successfully! Assigned ID: 101 📝 Title: Mastering JavaScript
5. Canceling Requests with AbortController
If a user types into a live search bar or navigates to another page, you can cancel any previous in-flight requests using AbortController to save network bandwidth.
const controller = new AbortController();
setTimeout(() => controller.abort(), 50);
fetch("https://jsonplaceholder.typicode.com/posts", { signal: controller.signal })
.then(res => res.json())
.catch(err => {
if (err.name === "AbortError") {
console.log("🛑 Request was successfully canceled by the user.");
}
});
🛑 Request was successfully canceled by the user.
6. Hands-On Practice: Robust JSON Fetch Helper
Write an async function safeFetchJson(url) that fetches data from url. If !res.ok, return { error: `HTTP ${res.status}` }; otherwise return the parsed JSON object.