Introduction to JavaScript Fetch API
Tags: javascript, webdev, beginners, codenewbie
Published: 2019-07-03 15:34:10


*This post was originally published on [attacomsian.com/blog](https://attacomsian.com/blog/javascript-fetch-api).*

---

The Fetch API is a [promise-based](https://attacomsian.com/blog/promises-javascript) JavaScript API for making asynchronous HTTP requests in the browser similar to XMLHttpRequest (XHR). Unlike XHR, it is a simple and clean API that uses promises to provides a more powerful and flexible feature set to fetch resources from the server.

Fetch is pretty much standardized now and is supported by all modern browsers except IE. If you need to support all browsers including IE, just add a [polyfill](https://github.com/github/fetch) released by GitHub to your project.

## API Usage

Using Fetch API is really simple. Just pass the URL, the path to the resource you want to fetch, to `fetch()` method: 

```javascript
fetch('/js/users.json')
    .then(response => {
        // handle response data
    })
    .catch(err => {
        // handle errors
    });
```

We pass the path for the resource we want to retrieve as a parameter to `fetch()`. It returns a promise that passes the response to `then()` when it is fulfilled. The `catch()` method intercepts errors if the request fails to complete due to network failure or any other reason.

## GET Request

By default, the Fetch API uses GET method for asynchronous requests. Let's use the [Reqres REST API](https://reqres.in) to retrieve a list of users using GET request:

```javascript
fetch('https://reqres.in/api/users')
    .then(res => res.json())
    .then(res => {
        res.data.map(user => {
            console.log(`${user.id}: ${user.first_name} ${user.last_name}`);
        });
    });
``` 

The above request prints the following on the console:

```plaintext
1: George Bluth
2: Janet Weaver
3: Emma Wong
```

Calling `fetch()` method returns a [promise](https://attacomsian.com/blog/promises-javascript). The response returned by the promise is a stream object which means that when we call `json()` method, it returns another promise. Call to `json()` method indicates that we are expecting a JSON response. If you are expecting an XML response, you should use `text()` method.

## POST Request

Just like [Axios](https://attacomsian.com/blog/axios-javascript), Fetch also allows to use any other HTTP method in the request: POST, PUT, DELETE, HEAD and OPTIONS. All you need to do is set the `method` and `body` parameters in the `fetch()` options:

```javascript
const user = {
    first_name: 'John',
    last_name: 'Lilly',
    job_title: 'Software Engineer'
};

const options = {
    method: 'POST',
    body: JSON.stringify(user),
    headers: {
        'Content-Type': 'application/json'
    }
}

fetch('https://reqres.in/api/users', options)
    .then(res => res.json())
    .then(res => console.log(res));
```

The Reqres API sends us the body data back with an ID and created timestamp attached:

```json
{  
   "first_name":"John",
   "last_name":"Lilly",
   "job_title":"Software Engineer",
   "id":"482",
   "createdAt":"2019-05-12T15:09:13.140Z"
}
```

## DELETE Request

The DELETE request looks very similar to the POST request except `body` is not required:

```javascript
const options = {
    method: 'DELETE',
    headers: {
        'Content-Type': 'application/json'
    }
}

fetch('https://reqres.in/api/users/2', options)
    .then(res => {
        if (res.ok) {
            return Promise.resolve('User deleted.');
        } else {
            return Promise.reject('An error occurred.');
        }
    })
    .then(res => console.log(res));
```

## Error Handling

Since `fetch()` method returns a promise, error handling is easy. We can use the `catch()` method of the promise to intercept any error that is thrown during the execution of the request. However, no error will be thrown if the request hits the server and comes back, regardless of what response was returned by the server. The promise returned by the `fetch()` doesn't reject on HTTP errors even if the HTTP response code is 404 or 500.

Fortunately, you can use the `ok` property of response object to check whether the request was successful or not:

```javascript
fetch('https://reqres.in/api/users/22') // 404 Error
    .then(res => {
        if (res.ok) {
            return res.json();
        } else {
            return Promise.reject(res.status);
        }
    })
    .then(res => console.log(res))
    .catch(err => console.log(`Error with message: ${err}`));
```

## Response Object

The response object returned by the `fetch()` method contains the information about the request and the response of the asynchronous call including headers, status code, and status message:

```javascript
fetch('https://reqres.in/api/users')
    .then(res => {
        console.log(res.headers.get('content-type'));
        console.log(res.headers.get('expires'));

        console.log(res.status);
        console.log(res.ok); // shorthand for `status` between 200 and 299 
        console.log(res.statusText);
        console.log(res.redirected);
        console.log(res.type);
        console.log(res.url);
    });
```

You can several options to access the response body of the Fetch API:

* `json()` returns the body as a JSON object
* `text()` returns the body as s string
* `blob()` returns the body as a Blob object
* `formData()` returns the body as a FormData object
* `arrayBuffer()` returns the body as an arrayBuffer object

All these methods return a promise. Here is an example of `text()` method:

```javascript
fetch('https://reqres.in/api/unknown/2')
    .then(res => res.text())
    .then(res => console.log(res));
```

The output of the above network call will be a JSON string:

```javascript
'{"data":{"id":2,"name":"fuchsia rose","year":2001,"color":"#C74375","pantone_value":"17-2031"}}'
```

## Fetch & Async/await

Since Fetch is a promise-based API, we can go one step further and use the latest ES2017 [async/await](https://attacomsian.com/blog/async-await-javascript) syntax to make our code even simpler and synchronous-looking:

```javascript
const fetchUsers = async () => {
    try {
        const res = await fetch('https://reqres.in/api/users');
        if (!res.ok) {
            throw new Error(res.status);
        }
        const data = await res.json();
        console.log(data);
    } catch (error) {
        console.log(error);
    }
}

fetchUsers();
```

## Conclusion

That's all folks for using JavaScript Fetch API. It is a huge improvement over `XMLHttpRequest` with an easy-to-use interface and works great for fetching resources (even across the network). The Fetch API is supported by all modern browsers, so there is no need to use any polyfill unless you want to support IE.

---

✌️ I write about **modern JavaScript, Node.js, Spring Boot**, and all things **web development**. [**Subscribe to my newsletter**](https://attacomsian.com/newsletter) to get web development tutorials & protips every week.

---

**Like this article?** [Follow @attacomsian on Twitter](https://twitter.com/attacomsian). You can also follow me on [LinkedIn](https://linkedin.com/in/attacomsian) and [DEV](https://dev.to/attacomsian).