what i learned last week: overview of fetch() 
Tags: javascript
Published: 2021-07-26 16:36:01

Credit: This entry is based on my learning about JavaScript from [Flatiron School](https://flatironschool.com/). 

First, to understand what the Fetch API does we need to understand what it is. In technical terms, the [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) provides an interface for fetching resources (including across the network) asynchronously. 

![pseudocode of how an API works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gbjtkbsvuw90hhrdyfcl.png)

Remember, an [API (Application Programming Interface)](https://en.wikipedia.org/wiki/API) is a connection between computers or between computer programs. It is a type of software interface, offering a service to other pieces of software.

![How An API Works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/923tcybrp3yruzpb4jtv.png)

The Fetch [API](https://developer.mozilla.org/en-US/docs/Web/API/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](https://caniuse.com/?search=fetch).

![Fetch Api](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dxs5ani02lp3eqbps76r.png)

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](https://developer.mozilla.org/en-US/docs/Web/HTTP/Overview).  

`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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) object represents the eventual completion (or failure) of an *asynchronous* operation and its resulting value.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gpew5du09lnfl5936wp4.png)

Remember, a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yjgobq07ybtyhpqmtmy1.png)

So what does this all mean? It means that a promise is an [object](https://www.deadcoderising.com/being-asynchronous-in-javascript-using-promises/) 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.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qb2xqde6avx1n995wlsm.gif)

We've learned a bit about `fetch()` and scraped, no pun intended, the surface on [asynchronous programming](https://searchnetworking.techtarget.com/definition/asynchronous). Lets go back to our Star Trek example and piece these different technologies together.

First, I'll practice [separation of concerns](https://en.wikipedia.org/wiki/Separation_of_concerns#:~:text=In%20computer%20science%2C%20separation%20of,code%20of%20a%20computer%20program.) 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](https://developer.mozilla.org/en-US/docs/Web/HTTP/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](https://www.w3.org/International/questions/qa-http-and-lang) 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](https://developer.mozilla.org/en-US/docs/Web/API/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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) 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);
  }); 
```