Javascript Fetch example: Get/Post/Put/Delete
Tags: javascript, webdev, todayilearned, beginners
Published: 2021-10-15 01:36:29

JavaScript Fetch API provides an interface for accessing and manipulating HTTP requests and responses. In this tutorial, we will create examples that use Javascript <code>fetch()</code> method to make Get/Post/Put/Delete request. The final section shows a simple Fetch HTTP Client to interact and get data from Rest API in Javascript.

Related Posts:
- [React Fetch example with Rest API](https://www.bezkoder.com/react-fetch-example/)
- <a href="https://www.bezkoder.com/vue-fetch-example/">Vue Fetch example with Rest API</a>
- <a href="https://www.bezkoder.com/axios-request/">Axios Tutorial: Get/Post/Put/Delete request example</a>

Full Article at [BezKoder](https://www.bezkoder.com/javascript-fetch/)

<h2>Javascript Fetch Overview</h2>
Javascript Fetch API has a global <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/fetch">fetch()</a></code> method that provides way to fetch resources asynchronously across the network.
<code>fetch()</code> returns a Promise that resolves with a <code>Response</code> object, which is fulfilled once the response is available.

```js
const responsePromise = fetch(resourceUrl [, options]);
```

A basic fetch request will look like this::

```js
fetch('/bezkoder.com/data')
  .then(response => response.json())
  .then(data => console.log(data));
```

<h2>Javascript Fetch Response Data</h2>
The <code>Response</code> object we mention above represents the entire HTTP response, it does not directly contain the response body. To get the actual JSON body of the response, we use following methods:
<ul>
	<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/arrayBuffer">response.arrayBuffer()</a>: returns a promise that resolves with an <code>ArrayBuffer</code>.</li>
	<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/blob">response.blob()</a>: returns a Promise that resolves with a <code>Blob</code>.</li>
	<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/error">response.error()</a>: returns a new Response object associated with a network error.</li>
	<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/formData">response.formData()</a>: returns a Promise that resolves with a <code>FormData</code>.</li>
	<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/json">response.json()</a>: returns a Promise that resolves with the result of parsing as JSON.</li>
	<li><a href="https://developer.mozilla.org/en-US/docs/Web/API/Response/text">response.text()</a>: returns a Promise that resolves with a text.</li>
</ul>

<h2>Javascript Fetch Response Metadata</h2>
We can also access metadata such as <code>headers</code>, <code>status</code>, <code>statusText</code>, <code>type</code>, <code>url</code> from the <code>Response</code> object:

```js
fetch('/bezkoder.com/data').then(function(response) {
    console.log(response.headers.get('Content-Type'));
    console.log(response.headers.get('Date'));

    console.log(response.status);
    console.log(response.statusText);
    console.log(response.type);
    console.log(response.url);
});
```

<h2>Fetch error handling</h2>
The response Promise does not reject on HTTP errors (for example: <code>404</code>, <code>500</code>). It only rejects when encountering a network error. So we must use <code>then()</code> to check for HTTP errors with <code>response.ok</code> status and/or <code>response.status</code> properties.

```js
fetch('/bezkoder.com/data')
  .then(function(response) {
    // if (response.status !== 200)
    if (!response.ok) {
       console.log('Error with Status Code: ' + response.status);
       return;
    }

    response.json().then(function(data) {
      console.log(data);
    });
  })
  .catch(function(err) {
    console.log('Error: ' + err);
  });
```

<h2>Fetch try catch async-await</h2>
If you want to use async-await, just wrap the fetch call with try/catch block.

```js
async function getData() {
  try {
    const response = await fetch('/bezkoder.com/data');

    if (!response.ok) {
      const message = 'Error with Status Code: ' + response.status;
      throw new Error(message);
    }

    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.log('Error: ' + err);
  }
}
```

<h2>Fetch with params</h2>
You can use <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/URL">URL</a></code> object with <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams">URLSearchParams</a></code> to set query string params.

```js
let url = new URL('/bezkoder.com/data');
const params = { title: 'web'};
url.search = new URLSearchParams(params);

try {
  const response = await fetch(url);

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

And this is equivalent:
```js
const response = await fetch('/bezkoder.com/data?title=web');
```

<h2>Fetch with headers</h2>
To send Fetch request with Headers, we pass an option object with <code>method</code> and <code>headers</code> property.

```js
const options = {
  method: 'get',
  headers: {
    "Content-Type": "application/json",
    "x-access-token": "token-value",
  }
};

try {
  const response = await fetch('/bezkoder.com/data', options);

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

<h2>Javascript Fetch POST</h2>
<h3>Fetch POST Form data</h3>
Let's create a POST request with <a href="https://developer.mozilla.org/en-US/docs/Web/API/FormData">Formdata</a> in the <code>body</code> of the request.

```js
let formData = new FormData();
formData.append('title', 'BezKoder Tutorial');
formData.append('description', 'Tut Desc');

try {
  const response = await fetch('/bezkoder.com/data', {
    method: "post",
    // headers: {
    //   "Content-Type": "application/x-www-form-urlencoded"
    // },
    body: formData
  });

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

If you use <code>application/x-www-form-urlencoded</code>, the keys and values are encoded in key-value tuples.

<h3>Fetch POST JSON</h3>
Let's create a POST request with JSON.

We use <code>JSON.stringify()</code> on the object before passing it in the <code>body</code> of the request and set <code>application/json</code> for the header <code>Content-Type</code>.

```js
const postData = {
  title: title,
  description: description,
};

try {
  const response = await fetch('/bezkoder.com/data', {
    method: "post",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(postData)
  });

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

<h3>Fetch POST file</h3>
Working with file is similar with previous one by using Form data.

```js
let formData = new FormData();
// formData.append('title', 'BezKoder Tutorial');
// formData.append('description', 'Tut Desc');
formData.append('file', file);

try {
  const response = await fetch('/bezkoder.com/data', {
    method: "post",
    body: formData
  });

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

We don't need to set the <code>Content-Type</code> header with <code>multipart/form-data</code>. The browser will automatically choose the appropriate content type header including form boundary.

<h2>Javascript Fetch PUT</h2>
Now we're gonna generate Fetch PUT example with JSON data. It's similar to Fetch POST request:
<ul>
	<li><code>method: "put"</code></li>
	<li><code>"Content-Type": "application/json"</code></li>
	<li>using <code>JSON.stringify()</code> on the object</li>
</ul>

```js
const postData = {
  title: title,
  description: description,
};

try {
  const response = await fetch('/bezkoder.com/data', {
    method: "put",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(postData)
  });

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

<h2>Fetch DELETE example</h2>

```js
try {
  const response = await fetch('/bezkoder.com/data/42', {
    method: "delete"
  });

  if (!response.ok) {
    const message = 'Error with Status Code: ' + response.status;
    throw new Error(message);
  }

  const data = await response.json();
  console.log(data);
} catch (error) {
  console.log('Error: ' + err);
}
```

<h2>Javascript Fetch example with Rest API</h2>
We will build a HTTP Client to make CRUD requests to Rest API in that:
<ul>
	<li>Fetch GET request: get all Tutorials, get Tutorial by Id, find Tutorial by title</li>
	<li>Fetch POST request: create new Tutorial</li>
	<li>Fetch PUT request: update an existing Tutorial</li>
	<li>Fetch DELETE request: delete a Tutorial, delete all Tutorials</li>
</ul>

<img src="https://www.bezkoder.com/wp-content/uploads/2021/10/javascript-fetch-api-tutorial-example.png" alt="javascript-fetch-api-tutorial-example" width="450" height="690" class="alignnone size-full wp-image-9791" />

This Fetch Client works with the following Web API:
<div class="table-responsive">
<table class="table table-hover  table table-hover" width="100%">
<thead>
<tr>
<th>Methods</th>
<th>Urls</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr>
<td>POST</td>
<td>/api/tutorials</td>
<td>create new Tutorial</td>
</tr>
<tr>
<td>GET</td>
<td>/api/tutorials</td>
<td>retrieve all Tutorials</td>
</tr>
<tr>
<td>GET</td>
<td>/api/tutorials/:id</td>
<td>retrieve a Tutorial by <code>:id</code></td>
</tr>
<tr>
<td>PUT</td>
<td>/api/tutorials/:id</td>
<td>update a Tutorial by <code>:id</code></td>
</tr>
<tr>
<td>DELETE</td>
<td>/api/tutorials/:id</td>
<td>delete a Tutorial by <code>:id</code></td>
</tr>
<tr>
<td>DELETE</td>
<td>/api/tutorials</td>
<td>delete all Tutorials</td>
</tr>
<tr>
<td>GET</td>
<td>/api/tutorials?title=[keyword]</td>
<td>find all Tutorials which title contains <code>keyword</code></td>
</tr>
</tbody>
</table>
</div>

You can find step by step to build a Server like this in one of these posts:
<ul>
	<li><a href="https://bezkoder.com/node-js-express-sequelize-mysql/">Express, Sequelize & MySQL</a></li>
	<li><a href="https://bezkoder.com/node-express-sequelize-postgresql/">Express, Sequelize & PostgreSQL</a></li>
	<li><a href="https://www.bezkoder.com/node-js-sql-server-crud/">Express, Sequelize & SQL Server</a></li>
	<li><a href="https://bezkoder.com/node-express-mongodb-crud-rest-api/">Express & MongoDb</a></li>
	<li><a href="https://bezkoder.com/spring-boot-jpa-crud-rest-api">Spring Boot & MySQL</a></li>
	<li><a href="https://bezkoder.com/spring-boot-postgresql-example/">Spring Boot & PostgreSQL</a></li>
	<li><a href="https://bezkoder.com/spring-boot-mongodb-crud/">Spring Boot & MongoDB</a></li>
	<li><a href="https://www.bezkoder.com/spring-boot-sql-server/">Spring Boot & SQL Server</a></li>
	<li><a href="https://bezkoder.com/spring-boot-jpa-h2-example/">Spring Boot & H2</a></li>
	<li><a href="https://bezkoder.com/spring-boot-cassandra-crud/">Spring Boot & Cassandra</a></li>
	<li><a href="https://bezkoder.com/spring-boot-hibernate-oracle/">Spring Boot & Oracle</a></li>
	<li><a href="https://bezkoder.com/django-crud-mysql-rest-framework/">Django & MySQL</a></li>
	<li><a href="https://bezkoder.com/django-postgresql-crud-rest-framework/">Django & PostgreSQL</a></li>
	<li><a href="https://bezkoder.com/django-mongodb-crud-rest-framework/">Django & MongoDB</a></li>
</ul>

For more details, please visit:
[https://www.bezkoder.com/javascript-fetch/](https://www.bezkoder.com/javascript-fetch/)

<h2>Conclusion</h2>
With this Javascript Fetch tutorial, you've known many ways to make GET/POST/PUT/DELETE request using Fetch API (with headers, params, body, form data...). You also know how to handle error in Fetch request or use async/await with try/catch statement.

Instead of Fetch API, you can also use Axios which is a promise-based HTTP Client Javascript library for Node.js and Browser. Kindly visit:
<a href="https://www.bezkoder.com/axios-request/">Axios Tutorial: Get/Post/Put/Delete request example</a>

Happy Learning! See you again.

<h2>Further Reading</h2>
Using Fetch with React:
[React Fetch example with Rest API](https://www.bezkoder.com/react-fetch-example/)

With Vue:
<a href="https://www.bezkoder.com/vue-fetch-example/">Vue Fetch example with Rest API</a>

You can apply it in one of following React/Vue applications (using fetch instead of axios):
<ul>
	<li><a href="https://www.bezkoder.com/react-crud-web-api/">React CRUD example with Axios</a></li>
	<li><a href="https://www.bezkoder.com/react-redux-crud-example/">React Redux CRUD example with Axios</a></li>
	<li><a href="https://www.bezkoder.com/vue-js-crud-app/">Vue 2 CRUD example with Axios</a></li>
	<li><a href="https://www.bezkoder.com/vue-3-crud/">Vue 3 CRUD example with Axios</a></li>
</ul>