Dmitri Pavlutin
I help developers understand JavaScript and React

How to Use fetch() with JSON

Posted July 28, 2021

JSON, which is a simple format of structured data, has become a popular format to send data over the network.

Here’s an example of JSON containing an object with props and values:

{
  "name": "Joker",
  "city": "Gotham",
  "isVillain": true,
  "friends": []
}

In this post, I’ll guide you on how to use fetch() API to load (usually using GET method) or post data (usually using a POST method) JSON data.

1. Recalling fetch()

fetch() accepts 2 arguments:

const response = await fetch(urlOrRequest[, options]);

The first obligatory argument of fetch() is the URL of the request, or generally a request object.

options, the optional second argument, lets you configure the request. The most useful options are:

  • options.method: the HTTP method to perform the request. Defaults to 'GET'
  • options.body: the body of the HTTP request
  • option.headers: an object with the headers to attach to the request

Calling fetch() starts a request and returns a promise. When the request completes, the promise resolves to the response object.

Response object provides useful methods to extract data from a multitude of formats. But to parse data from JSON you need just one method — response.json().

2. GET JSON data

Let’s fetch from the path /api/names a list of persons in JSON format:

async function loadNames() {
  const response = await fetch('/api/names');
  const names = await response.json();

  console.log(names); 
  // logs [{ name: 'Joker'}, { name: 'Batman' }]
}

loadNames();

await fetch('/api/names') starts a GET request, and evaluates to the response object when the request is complete.

Then, from the server response, you can parse the JSON into a plain JavaScript object using await response.json() (note: response.json() returns a promise!).

By default fetch() performs a GET request. But you can always indicate the HTTP method explicitly:

// ...
const response = await fetch('/api/names', {
  method: 'GET'});
// ...

2.1 Explicitly asking for JSON

Some API servers might work with multiple formats: JSON, XML, etc. That’s why these servers might require you to indicate the format of the posted data.

To do so you need to use the headers option, and specifically set Accept header to application/json to explicitly ask for JSON:

// ...
const response = await fetch('/api/names', {
  headers: {    'Accept': 'application/json'  }});
// ...

3. POST JSON data

POST-ing JSON data to the server is slightly trickier.

First, you need to set a couple of parameters on the fetch(), particularly indicate the HTTP method as 'POST'.

Second, you need to set the body parameter with the object stringified as JSON.

async function postName() {
  const object = { name: 'James Gordon' };
  const response = await fetch('/api/names', {
    method: 'POST',    body: JSON.stringify(object)  });

  const responseText = await response.text();
  console.log(responseText); // logs 'OK'
}

postName();

Take a look at body option value. JSON.stringify(object) utility function is used to transform a JavaScript object into a JSON string.

body option accepts a string, but not an object.

This approach works also when performing POST, but as well PUT or PATCH requests.

3.1 Explicitly posting JSON

Again, some servers might require you to indicate explicitly that you POST (or PATCH, or PUT) data in JSON format.

In such a case you can indicate the content type of data you’re pushing, particularly setting the Content-Type header to application/json.

// ...
const object = { name: 'James Gordon' };

const response = await fetch('/api/names', {
  method: 'POST',
  body: JSON.stringify(object),  headers: {    'Content-Type': 'application/json'  }
});
// ...

4. Using a request object

In the examples above I was using the options argument of fetch() to set the method, headers, and body.

But sometimes you might want to encapsulate the request data into an object, especially when implementing a middleware. You can create request objects using the same options using the Request constructor.

For example, let’s post JSON data by creating a request object:

// ...
const object = { name: 'James Gordon' };

const request = new Request('/api/names', {
  method: 'POST',
  body: JSON.stringify(object),
  headers: {
    'Content-Type': 'application/json'
  }
});

const response = await fetch(request);

// ...

5. Conclusion

This is pretty much all the main information you need to load or post JSON data to the server using fetch().

When loading data, make sure to extract and parse JSON to an actual object from the response using const object = await response.json() method.

But when posting JSON data, make sure to indicate the stringified object into a JSON string using JSON.stringify(object). Assign the JSON to body option of the request.

Would you like to know more on how to use fetch()? I recommend checking How to Use Fetch with async/await.

Like the post? Please share!

Quality posts into your inbox

I regularly publish posts containing:

  • Important JavaScript concepts explained in simple words
  • Overview of new JavaScript features
  • How to use TypeScript and typing
  • Software design and good coding practices

Subscribe to my newsletter to get them right into your inbox.

Join 4128 other subscribers.

About Dmitri Pavlutin

Software developer, tech writer and coach. My daily routine consists of (but not limited to) drinking coffee, coding, writing, coaching, overcoming boredom 😉.
Email addressTwitter profileFacebook pageLinkedIn profile