Javascript Fetch: Get/Post/Put/Delete example

JavaScript Fetch API provides an interface for accessing and manipulating HTTP requests and responses. In this tutorial, we will create examples that use Javascript fetch() 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 Post: Axios Tutorial: Get/Post/Put/Delete request example


Javascript Fetch Overview

Javascript Fetch API has a global fetch() method that provides way to fetch resources asynchronously across the network.
fetch() returns a Promise that resolves with a Response object, which is fulfilled once the response is available.

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

A basic fetch request will look like this::

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

Javascript Fetch Response Data

The Response 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:

Javascript Fetch Response Metadata

We can also access metadata such as headers, status, statusText, type, url from the Response object:

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);
});

Fetch error handling

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

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);
  });

Fetch try catch async-await

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

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);
  }
}

Fetch with params

You can use URL object with URLSearchParams to set query string params.

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:

const response = await fetch('/bezkoder.com/data?title=web');

Fetch with headers

To send Fetch request with Headers, we pass an option object with method and headers property.

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);
}

Javascript Fetch POST

Fetch POST Form data

Let’s create a POST request with Formdata in the body of the request.

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 application/x-www-form-urlencoded, the keys and values are encoded in key-value tuples.

Fetch POST JSON

Let’s create a POST request with JSON.

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

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);
}

Fetch POST file

Working with file is similar with previous one by using Form data.

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 Content-Type header with multipart/form-data. The browser will automatically choose the appropriate content type header including form boundary.

Javascript Fetch PUT

Now we’re gonna generate Fetch PUT example with JSON data. It’s similar to Fetch POST request:

  • method: "put"
  • "Content-Type": "application/json"
  • using JSON.stringify() on the object
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);
}

Fetch DELETE example

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);
}

Javascript Fetch example with Rest API

We will build a HTTP Client to make CRUD requests to Rest API in that:

  • Fetch GET request: get all Tutorials, get Tutorial by Id, find Tutorial by title
  • Fetch POST request: create new Tutorial
  • Fetch PUT request: update an existing Tutorial
  • Fetch DELETE request: delete a Tutorial, delete all Tutorials

javascript-fetch-api-tutorial-example

This Fetch Client works with the following Web API:

MethodsUrlsActions
POST/api/tutorialscreate new Tutorial
GET/api/tutorialsretrieve all Tutorials
GET/api/tutorials/:idretrieve a Tutorial by :id
PUT/api/tutorials/:idupdate a Tutorial by :id
DELETE/api/tutorials/:iddelete a Tutorial by :id
DELETE/api/tutorialsdelete all Tutorials
GET/api/tutorials?title=[keyword]find all Tutorials which title contains keyword

You can find step by step to build a Server like this in one of these posts:

Remember that you need to configure CORS: Access-Control-Allow-Origin: *.
It helps the REST APIs can be accessed by any origin.

– Create a Tutorial using Fetch POST request:

fetch-post-example

– Retrieve all Tutorials using Fetch GET request:

fetch-example

– Retrieve a Tutorial by Id using Fetch GET request:

js-fetch-example

– Find Tutorials by title using Fetch with params:

fetch-with-params

– Update a Tutorial using Fetch PUT request:

fetch-put-example

– Delete Tutorial using Fetch DELETE request:

fetch-delete-example

Source Code

index.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Fetch Requests example</title>
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
    />
  </head>
  <body>
    <div class="container my-3" style="max-width: 600px">
      <h3>Fetch Requests example</h3>

      <div class="card mt-3">
        <div class="card-header">Fetch GET Request - BezKoder.com</div>
        <div class="card-body">
          <div class="input-group input-group-sm">
            <button class="btn btn-sm btn-primary" onclick="getAllData()">Get All</button>

            <input type="text" id="get-id" class="form-control ml-2" placeholder="Id">
            <div class="input-group-append">
              <button class="btn btn-sm btn-primary" onclick="getDataById()">Get by Id</button>
            </div>

            <input type="text" id="get-title" class="form-control ml-2" placeholder="Title">
            <div class="input-group-append">
              <button class="btn btn-sm btn-primary" onclick="getDataByTitle()">Find By Title</button>
            </div>

            <button class="btn btn-sm btn-warning ml-2" onclick="clearGetOutput()">Clear</button>
          </div>   
          
          <div id="getResult"></div>
        </div>
      </div>

      <div class="card mt-3">
        <div class="card-header">Fetch POST Request - BezKoder.com</div>
        <div class="card-body">
          <div class="form-group">
            <input type="text" class="form-control" id="post-title" placeholder="Title">
          </div>
          <div class="form-group">
            <input type="text" class="form-control" id="post-description" placeholder="Description">
          </div>
          <button class="btn btn-sm btn-primary" onclick="postData()">Post Data</button>
          <button class="btn btn-sm btn-warning" onclick="clearPostOutput()">Clear</button>

          <div id="postResult"></div>
        </div>
      </div>

      <div class="card mt-3">
        <div class="card-header">Fetch PUT Request - BezKoder.com</div>
        <div class="card-body">
          <div class="form-group">
            <input type="text" class="form-control" id="put-id" placeholder="Id">
          </div>
          <div class="form-group">
            <input type="text" class="form-control" id="put-title" placeholder="Title">
          </div>
          <div class="form-group">
            <input type="text" class="form-control" id="put-description" placeholder="Description">
          </div>
          <div class="form-check mb-2">
            <input type="checkbox" class="form-check-input" id="put-published">
            <label class="form-check-label" for="put-published">Publish</label>
          </div>
          <button class="btn btn-sm btn-primary" onclick="putData()">Update Data</button>
          <button class="btn btn-sm btn-warning" onclick="clearPutOutput()">Clear</button>

          <div id="putResult"></div>
        </div>
      </div>

      <div class="card mt-3">
        <div class="card-header">Fetch DELETE Request - BezKoder.com</div>
        <div class="card-body">
          <div class="input-group input-group-sm">
            <button class="btn btn-sm btn-danger" onclick="deleteAllData()">Delete All</button>

            <input type="text" id="delete-id" class="form-control ml-2" placeholder="Id">
            <div class="input-group-append">
              <button class="btn btn-sm btn-danger" onclick="deleteDataById()">Delete by Id</button>
            </div>

            <button class="btn btn-sm btn-warning ml-2" onclick="clearDeleteOutput()">Clear</button>
          </div>    
          
          <div id="deleteResult"></div>      
        </div>
      </div>

      <p class="mt-3">
        ©
        <a href="https://www.bezkoder.com/fetch-request" target="_blank">bezkoder.com</a>
      </p>
    </div>

    <script src="main.js"></script>
  </body>
</html>

main.js

const baseURL = "http://localhost:8080/api";

function htmlizeResponse(res) {
  return (
    `<div class="alert alert-secondary mt-2" role="alert"><pre>` +
    JSON.stringify(res, null, 2) +
    "</pre></div>"
  );
}

async function getAllData() {
  let resultElement = document.getElementById("getResult");
  resultElement.innerHTML = "";

  try {
    const res = await fetch(`${baseURL}/tutorials`);

    if (!res.ok) {
      const message = `An error has occured: ${res.status} - ${res.statusText}`;
      throw new Error(message);
    }

    const data = await res.json();

    const result = {
      status: res.status + "-" + res.statusText,
      headers: {
        "Content-Type": res.headers.get("Content-Type"),
        "Content-Length": res.headers.get("Content-Length"),
      },
      length: res.headers.get("Content-Length"),
      data: data,
    };

    resultElement.innerHTML = htmlizeResponse(result);
  } catch (err) {
    resultElement.innerHTML = htmlizeResponse(err.message);
  }
}

async function getDataById() {
  let resultElement = document.getElementById("getResult");
  resultElement.innerHTML = "";

  const id = document.getElementById("get-id").value;

  if (id) {
    try {
      const res = await fetch(`${baseURL}/tutorials/${id}`);

      if (!res.ok) {
        const message = `An error has occured: ${res.status} - ${res.statusText}`;
        throw new Error(message);
      }

      const data = await res.json();

      const result = {
        data: data,
        status: res.status,
        statusText: res.statusText,
        headers: {
          "Content-Type": res.headers.get("Content-Type"),
          "Content-Length": res.headers.get("Content-Length"),
        },
      };

      resultElement.innerHTML = htmlizeResponse(result);
    } catch (err) {
      resultElement.innerHTML = htmlizeResponse(err.message);
    }
  }
}

async function getDataByTitle() {
  let resultElement = document.getElementById("getResult");
  resultElement.innerHTML = "";

  const title = document.getElementById("get-title").value;

  if (title) {
    try {
      // const res = await fetch(`${baseURL}/tutorials?title=${title}`);

      let url = new URL(`${baseURL}/tutorials`);
      const params = { title: title };
      url.search = new URLSearchParams(params);

      const res = await fetch(url);

      if (!res.ok) {
        const message = `An error has occured: ${res.status} - ${res.statusText}`;
        throw new Error(message);
      }

      const data = await res.json();

      const result = {
        status: res.status + "-" + res.statusText,
        headers: {
          "Content-Type": res.headers.get("Content-Type"),
          "Content-Length": res.headers.get("Content-Length"),
        },
        data: data,
      };

      resultElement.innerHTML = htmlizeResponse(result);
    } catch (err) {
      resultElement.innerHTML = htmlizeResponse(err.message);
    }
  }
}

async function postData() {
  let resultElement = document.getElementById("postResult");
  resultElement.innerHTML = "";

  const title = document.getElementById("post-title").value;
  const description = document.getElementById("post-description").value;

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

  try {
    const res = await fetch(`${baseURL}/tutorials`, {
      method: "post",
      headers: {
        "Content-Type": "application/json",
        "x-access-token": "token-value",
      },
      body: JSON.stringify(postData),
    });

    if (!res.ok) {
      const message = `An error has occured: ${res.status} - ${res.statusText}`;
      throw new Error(message);
    }

    const data = await res.json();

    const result = {
      status: res.status + "-" + res.statusText,
      headers: {
        "Content-Type": res.headers.get("Content-Type"),
        "Content-Length": res.headers.get("Content-Length"),
      },
      data: data,
    };

    resultElement.innerHTML = htmlizeResponse(result);
  } catch (err) {
    resultElement.innerHTML = htmlizeResponse(err.message);
  }
}

async function putData() {
  let resultElement = document.getElementById("putResult");
  resultElement.innerHTML = "";

  const id = document.getElementById("put-id").value;
  const title = document.getElementById("put-title").value;
  const description = document.getElementById("put-description").value;
  const published = document.getElementById("put-published").checked;

  const putData = {
    title: title,
    description: description,
    published: published,
  };

  try {
    const res = await fetch(`${baseURL}/tutorials/${id}`, {
      method: "put",
      headers: {
        "Content-Type": "application/json",
        "x-access-token": "token-value",
      },
      body: JSON.stringify(putData),
    });

    if (!res.ok) {
      const message = `An error has occured: ${res.status} - ${res.statusText}`;
      throw new Error(message);
    }

    const data = await res.json();

    const result = {
      status: res.status + "-" + res.statusText,
      headers: { "Content-Type": res.headers.get("Content-Type") },
      data: data,
    };

    resultElement.innerHTML = htmlizeResponse(result);
  } catch (err) {
    resultElement.innerHTML = htmlizeResponse(err.message);
  }
}

async function deleteAllData() {
  let resultElement = document.getElementById("deleteResult");
  resultElement.innerHTML = "";

  try {
    const res = await fetch(`${baseURL}/tutorials`, { method: "delete" });

    const data = await res.json();

    const result = {
      status: res.status + "-" + res.statusText,
      headers: { "Content-Type": res.headers.get("Content-Type") },
      data: data,
    };

    resultElement.innerHTML = htmlizeResponse(result);
  } catch (err) {
    resultElement.innerHTML = htmlizeResponse(err.message);
  }
}

async function deleteDataById() {
  let resultElement = document.getElementById("deleteResult");
  resultElement.innerHTML = "";

  const id = document.getElementById("delete-id").value;

  try {
    const res = await fetch(`${baseURL}/tutorials/${id}`, { method: "delete" });

    const data = await res.json();

    const result = {
      status: res.status + "-" + res.statusText,
      headers: { "Content-Type": res.headers.get("Content-Type") },
      data: data,
    };

    resultElement.innerHTML = htmlizeResponse(result);
  } catch (err) {
    resultElement.innerHTML = htmlizeResponse(err.message);
  }
}

function clearGetOutput() {
  document.getElementById("getResult").innerHTML = "";
}

function clearPostOutput() {
  document.getElementById("postResult").innerHTML = "";
}

function clearPutOutput() {
  document.getElementById("putResult").innerHTML = "";
}

function clearDeleteOutput() {
  document.getElementById("deleteResult").innerHTML = "";
}

Conclusion

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:
Axios Tutorial: Get/Post/Put/Delete request example

Happy Learning! See you again.

Further Reading

You can apply it in one of following React/Vue applications (using fetch instead of axios):

Leave a Reply

Your email address will not be published. Required fields are marked *