16
what i learned last week: overview of fetch()
Credit: This entry is based on my learning about JavaScript from Flatiron School.
First, to understand what the Fetch API does we need to understand what it is. In technical terms, the Fetch API provides an interface for fetching resources (including across the network) asynchronously.
Remember, an API (Application Programming Interface) is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software.
The Fetch API allows us to create a "micro dimension" within our browser and fetch resources, again, asynchronously. I know that is a mind bending statement but that analogy has helped me think of API's in an abstract way.
IMPORTANT
Fetch is an API made available by, not all but most, browsers. The fact that this API is available on browsers which in turns gives us the ability to write asynchronous code is the reason that JavaScript is so powerful, in my humble opinion. If you want to check your browser compatibility please click here.
Let's talk about what actually happens within this micro dimension we've created in our browser. Just like how we can use a browser for a variety of actions we can use this newly created dimension to go to a website using a URL. The first thing you'll want to do is pass in a URL as an argument - which is mandatory.
The code below tells our browser "hey, take me here." It does this by making a network request using HTTP protocol.
fetch("https://www.startrek.com/")
Remember, HTTP is a protocol which allows the fetching of resources, such as HTML documents. It is the foundation of any data exchange on the Web and it is a client-server protocol, which means requests are initiated by the recipient, usually the Web browser.
Let's build on our above example and say that we want to access an API endpoint that has a list of planets featured in the Star Trek series.
fetch("https://www.startrek.com/planets")
.then(planets => {
/* Do work with returned planets */
})
fetch()
takes in a URL as an argument and chained to the method is a call to .then()
which returns a promise. The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.
Remember, a Promise is a proxy for a value not necessarily known when the promise is created. Also, a Promise is only ever in one of these states.
Pending: initial state, neither fulfilled nor rejected.
Fulfilled: meaning that the operation was completed successfully.
Rejected: meaning that the operation failed.
So what does this all mean? It means that a promise is an object that represents an asynchronous computation that eventually will complete. This way we don't have to wait for the computation to finish. Instead we can create multiple promises that can do different work, and we can handle the result when they're finished.
We've learned a bit about fetch()
and scraped, no pun intended, the surface on asynchronous programming. Lets go back to our Star Trek example and piece these different technologies together.
First, I'll practice separation of concerns and create an object that is saved within the formData
variable. This object allows us to send multiple pieces of information in one request. Note, we are going to use this object in a bit and it's important that you remember that we can't assign formData
to our configObj
's body property because it is not a string.
let formData = {
planetName: "Vulcan",
planetRegion: "40 Eridani,"
};
As I just alluded, with the power of fetch()
we can not only retrieve data we can also mutate and delete it. HTTP defines a set of request methods to indicate the desired action to be performed for a given resource. Some of those methods are GET, POST/PATCH and DELETE. For this example we are going to use POST
. This method is used to submit an entity to the specified resource, often causing a change in state or side effects on the server.
Next, when you retrieve a web page or resource from a server, the server sends with it various bits of information about the thing you are retrieving (metadata). It uses a format referred to as headers.
Lastly, we need to add a body
property to configObj
and pass in a string as it's value.
Remember, right now we can't assign the formData
object to our configObj
's body
property as a value because it is not a string.
We solve this by passing JSON.stringify()
to our body
and passing in configObj
as it's single argument.
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
let configObj = {
method: "POST", // The default value is always GET
headers: {
"Content-Type": "application/json", // indicate what format the data being sent is in. With JavaScript's
"Accept": "application/json" // advertises which content types, expressed as MIME types, the client is able to understand
},
body: JSON.stringify(formData) /* Your data goes here */
};
Finally, with our configObj
and formData
now all set up we can NOW focus on fetch()
and make a POST
request to the Star Trek API endpoint.
fetch("http://startrek/planets", configObj)
.then(function(response) {
return response.json();
})
.then(function(object) {
console.log(object);
});
Full Example
let formData = {
planetName: "Vulcan",
planetRegion: "40 Eridani,"
};
let configObj = {
method: "POST",
headers: {
"Content-Type": "application/json",
"Accept": "application/json"
},
body: JSON.stringify(formData)
};
fetch("http://startrek/planets", configObj)
.then(function(response) {
return response.json();
})
.then(function(object) {
console.log(object);
});
16