Using fetch() to Make HTTP Requests in JavaScript

The fetch() API is a built-in JavaScript method for making network requests. It’s promise-based, allowing for easier handling of asynchronous operations compared to older methods like XMLHttpRequest. With fetch(), you can send HTTP requests to retrieve data (GET), send data (POST), update resources (PUT and PATCH), and delete data (DELETE) from a server.


1. Basic Syntax of fetch()

The fetch() function takes a URL as a parameter and returns a promise that resolves to the Response object. This response can be used to extract data in different formats, such as JSON, text, or Blob.

Basic Example

fetch("https://jsonplaceholder.typicode.com/posts/1")
.then((response) => response.json()) // Convert response to JSON
.then((data) => {
console.log("Data:", data); // Log the data
})
.catch((error) => {
console.error("Error:", error); // Handle errors
});

In this example:

  • The fetch() function sends a GET request to retrieve a specific post.
  • The .then() method processes the response.
  • .catch() is used to handle any errors that might occur during the request.

2. Handling Response Formats

The fetch() response object offers several methods to convert the data into usable formats:

  • response.json(): Parses JSON data.
  • response.text(): Parses plain text.
  • response.blob(): Retrieves binary data, like images or PDFs.

Example: Retrieving Text Data

fetch("https://example.com/data.txt")
.then((response) => response.text())
.then((text) => {
console.log("Text data:", text);
})
.catch((error) => {
console.error("Error:", error);
});

This example demonstrates how to retrieve and log plain text data from a server.


3. Using HTTP Methods with fetch()

The fetch() API supports all standard HTTP methods by specifying them in the options object passed as the second parameter.

GET Request

A GET request is the default method for fetch() and doesn’t require any configuration.

fetch("https://jsonplaceholder.typicode.com/posts")
.then((response) => response.json())
.then((data) => console.log(data));

POST Request

A POST request sends data to the server. This requires the method option, the headers to specify content type, and a body to hold the data being sent.

fetch("https://jsonplaceholder.typicode.com/posts", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "New Post",
body: "This is the content of the new post.",
userId: 1,
}),
})
.then((response) => response.json())
.then((data) => console.log("Created:", data))
.catch((error) => console.error("Error:", error));

In this example, fetch() sends a POST request with data in JSON format to create a new post.

PUT Request

A PUT request replaces an existing resource with new data. Like POST, it requires method, headers, and body options.

fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PUT",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Updated Post",
body: "This post has been updated.",
}),
})
.then((response) => response.json())
.then((data) => console.log("Updated:", data))
.catch((error) => console.error("Error:", error));

This PUT request updates an existing post with new content.

PATCH Request

A PATCH request partially updates a resource, sending only the modified fields.

fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "PATCH",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
title: "Partially Updated Title",
}),
})
.then((response) => response.json())
.then((data) => console.log("Partially Updated:", data))
.catch((error) => console.error("Error:", error));

Here, the PATCH request only updates the title field, leaving other fields unchanged.

DELETE Request

A DELETE request removes a resource from the server. DELETE requests often do not require a body.

fetch("https://jsonplaceholder.typicode.com/posts/1", {
method: "DELETE",
})
.then((response) => {
if (response.ok) {
console.log("Deleted successfully");
} else {
console.error("Delete failed");
}
})
.catch((error) => console.error("Error:", error));

This DELETE request removes the specified post from the server.


4. Handling Errors in fetch()

By default, fetch() only rejects if there is a network error, not for HTTP errors like 404 or 500. To handle these, check the response status.

Example of Error Handling

fetch("https://jsonplaceholder.typicode.com/posts/invalid")
.then((response) => {
if (!response.ok) {
throw new Error("Network response was not ok: " + response.status);
}
return response.json();
})
.then((data) => console.log("Data:", data))
.catch((error) => console.error("Error:", error));

In this example:

  • The response.ok property checks if the request was successful.
  • If ok is false, it throws an error, which is then caught in the .catch() block.

5. Best Practices for Using fetch()

  • Always handle errors: Use .catch() and check response.ok to handle both network and HTTP errors.
  • Set appropriate headers: Always specify Content-Type when sending JSON data.
  • Use async/await for readability: For cleaner syntax, use async functions with await for multiple fetch calls.
  • Rate limiting and retries: If an API has rate limits, consider adding retry logic or limiting the frequency of requests.

Example Using Async/Await

async function fetchData() {
try {
const response = await fetch("https://jsonplaceholder.typicode.com/posts/1");
if (!response.ok) {
throw new Error("Network response was not ok");
}
const data = await response.json();
console.log("Data:", data);
} catch (error) {
console.error("Error:", error);
}
}

fetchData();

This example uses async/await to make the code more readable and maintainable.


Exercises


  1. Basic GET Request
    • Objective: Practice making a GET request.
    • Instructions: Use fetch to retrieve a list of posts from https://jsonplaceholder.typicode.com/posts. Log the data or an error message.
  2. POST Request to Create Data
    • Objective: Practice using fetch to send data to a server.
    • Instructions: Use fetch to send a POST request to https://jsonplaceholder.typicode.com/posts to create a new post with a title and body. Log the response or an error message.
  3. PUT Request to Update Data
    • Objective: Practice using fetch to update existing data.
    • Instructions: Use fetch to send a PUT request to https://jsonplaceholder.typicode.com/posts/1 to update the title and body of a post. Log the updated data or an error message.
  4. Error Handling in Fetch
    • Objective: Practice handling HTTP errors.
    • Instructions: Use fetch to make a GET request to an invalid URL on https://jsonplaceholder.typicode.com. Check if response.ok is false, throw an error, and handle it with .catch().
  5. Using Async/Await with Fetch
    • Objective: Practice using async/await with fetch.
    • Instructions: Write an async function that makes a GET request to https://jsonplaceholder.typicode.com/users/1. Log the data or catch any errors if the request fails.

Multiple-Choice Questions


  1. What does fetch() return?
    • A) A JSON object
    • B) An XMLHttpRequest object
    • C) A promise that resolves to a Response object
    • D) A promise that resolves to the data directly
    Answer: C. fetch() returns a promise that resolves to a Response object.
  2. Which method is used to parse JSON from a fetch() response?
    • A) .text()
    • B) .blob()
    • C) .parseJSON()
    • D) .json()
    Answer: D. .json() is used to parse JSON data from a fetch() response.
  3. What does the Content-Type header application/json specify?
    • A) The response will contain JSON data
    • B) The request body contains JSON data
    • C) The request will return HTML data
    • D) The server should ignore the request body
    Answer: B. Content-Type: application/json specifies that the request body contains JSON data.
  4. Which of the following is true about error handling in fetch()?
    • A) fetch() rejects for all HTTP errors
    • B) fetch() only rejects for network errors
    • C) fetch() automatically retries failed requests
    • D) fetch() does not support error handling
    Answer: B. fetch() only rejects for network errors, not HTTP errors.
  5. What does the following code do?javascriptCopy codefetch("https://jsonplaceholder.typicode.com/posts", { method: "DELETE" });
    • A) Creates a new post
    • B) Retrieves a list of posts
    • C) Updates an existing post
    • D) Deletes a specific post
    Answer: D. Deletes a specific post, assuming an ID is provided in the URL.