The Fetch API is a specialized version of promises for network requests. It's a special API that we can use to fetch information over the network or read/write to files. It's natively available in JavaScript, so there's no need to install any third-party tools.
The Fetch API is a promise structure built into JavaScript, specialized for network requests. It can be used to fetch data over the network or for file read/write operations, and doesn't require any third-party installations.
It's an asynchronous code block that goes into the micro task queue, i.e., the 2nd queue.
We can perform CRUD operations with fetch. When we say fetch("url"), it's directly a GET request.
fetch("url", {method: 'POST', body: JSON.stringify(data), headers: {"X-Auth-Token" : "abc123"}})
Some APIs might be encrypted, requiring the password to be sent under headers. In the body section, we send the content.
We perform CRUD operations like GET, POST, PUT, DELETE with the FETCH API.
What is an API?
Everything in the internet environment revolves around APIs.
The JSON formatter extension helps us view the data in a nice way.
External-dependent long-running operations are generally done asynchronously. If we don't make them asynchronous, other commands might take 2 or 3 seconds; it blocks other code until the code runs. Therefore, external-dependent long-running operations like network requests, input-output requests, file reading, file writing, sending data to a printer are generally done asynchronously. There's an API written for network operations; we use the Fetch API for this.
It's difficult to perform POST, PUT operations from the browser. You can't do operations like sending data, making those settings, sending tokens. Such operations are either done within the application, or there are tools related to this. Like Postman, like Thunder, etc.
First, we call the fetch function, then we specify the address we'll send the request to. Unless specified otherwise, it sends a GET request. We catch the request we sent with thens. The fetch part returns data to us. Actually, it returns a Response. Its prototype is Response. Response is also derived from Object. So its ancestor is still Object, its immediate ancestor is Response. We don't see the data we want here, the JSON data, because this returns raw data to us. That is, a wrapped Response data.
fetch("https://api.github.com/users").then((res) => console.log(res))
The code above returns an enclosed data (readable stream), which needs to be opened.
https://developer.mozilla.org/en-US/docs/Web/HTTP/Messages
HTTP messages are the fundamental building blocks that explain how data exchange occurs between server and client. These messages are divided into two main types:
- Requests sent by the client to the server, aiming to initiate an action on the server
- Responses given by the server to these requests
Both types of messages have a similar structure and consist of the following components:
- Start-line: A single-line description stating what the request is or the status of the response
- HTTP headers: Optional information that further describes the request or response
- Empty line: A separator indicating the end of the header information
- Body: Optionally, the section containing data associated with the request or response
This structure forms the basis of HTTP communication and allows web developers to understand and manage server-client interactions.
You can think of this like HTML, where basic information is in the head, while information is sent from the body, etc.
The header contains basic configuration information, passwords, etc.
The body contains the payload, that is, the loaded data, as an object.
Its return has a header and body (Response).
fetch("https://api.github.com/users")
.then((res) => {
console.log(res)
return res.json()
})
.then((res) => console.log(res))
Here, the information returned in the body is opened using JSON.
JSON.stringify converts an object (for example, this could be a JSON object) into a plain string. The JSON function extracts the information inside the body, which is a ReadableStream, and converts it to JSON format.
Above, we JSON-ify the data in the first then. This process can be time-consuming, so it needs to be asynchronous. Once we're sure it's finished with the first then, we can pass it to another place for processing with a second then. It's like we've cracked open a walnut and taken out the nut inside.
In the first phase, response is used, and in the second phase, data is used. This is for best practice.
We're sending a request to a remote network, opening the data it sends and making it processable. Because we'll be presenting this to the user.
The JSON-ification process happens in the first then. Because this process can take some time. After that, we take the JSON-ified data and send it somewhere else for processing. So the first then can be a time-consuming process, that's why it needs to be asynchronous. Once we're sure it's finished, we can pass it to another place for use with a second then.
fetch("https://api.github.com/user")
.then((res) => {
console.log(res)
return res.json()
})
.then((res) => console.log(res))
.catch((err) => document.write(err))
Reasons for errors: you might have provided an incorrect URL; there could be a network error, packets might be corrupted, information might not be sent or could be corrupted; it could be an encrypted API and you might have entered the wrong password; another error could be that you want to send a POST request but you sent a PUT request instead: method mismatch, etc.
When any of these errors occur, I would expect it not to enter the 'then' blocks, but to enter the 'catch' block. While in a Promise it would go directly to catch, it doesn't with fetch. This is related to the Fetch API; this API is an optimistic API. If it receives any data, it says "I got my data" and doesn't enter the catch. Therefore, in the Fetch API, we need to control whether it returns successfully or unsuccessfully. We look at the "ok" status in the information returned from the Response.
Even when there's an error, the 'then' blocks also run. It doesn't directly execute the catch like in a promise. Therefore, we need to handle the data ourselves. With throw, we throw an error if there's an issue with res.ok, and it goes directly to catch.
Status codes between 200 and 299 are successful.
fetch("https://api.github.com/user")
.then((res) => {
console.log(res)
if(!res.ok) {
throw new Error(`Something went wrong ${res.status}`)
}
return res.json()
})
.then((res) => console.log(res))
.catch((err) => document.write(err))
If there's an error when we make a request, the return won't work, and we handle the error in the catch block. In the then block after JSON-ification, it's generally used as "data" rather than "res".
Leave a reply