Why handle fetch with two then methods?

I see the fetch() pattern uses two then() methods to handle data when successful, but i dont understand why?

Hello there,

I assume you are referring to something like:

fetch('some-url').then(res = > res.json()).then(data => console.log(data));

If so, this is because there are two asynchronous actions taking place:

  1. fetch returns a promise
  2. .json() returns a promise

If you want to see some of the internals, you could try:

fetch('https://freecodecamp.org/sky020').then(res => console.log(res));

Note: you are likely to get CORS errors, but the principle is still the same

Nowadays, I prefer reading through the async/await syntax:

const res = await fetch('some-url');
const data = await res.json();

Hope this helps

1 Like

ok that makes sense. I think i didnt evaluate that json() returns a promise and im likely to need to use it.
How come the XMLHttpRequest method doesnt use json() but directly JSON.parse() etc?

Well, .json() and JSON... are not comparable. Looking at an example:

const req = new XMLHttpRequest();
req.onload = function(){
  const json = JSON.parse(req.responseText);
  // Do something with json

In this instance, it would be more comparable to take req.onload as being similar to the .then method. However, the main difference in this case is req.responseText is nothing but a string - it only has string methods (i.e. no .json() method).

So, if you want to use a string as an object (specifically, a JSON object), you need to convert (parse) the string into an object. Essentially (an example),

req.responseText = "{someProperty: \"some value\", key: \"value\"}";

Now, parsing text (a string) does not need to happen asynchronously. I can write my own parser:

const responseText = "{someProperty: \"some value\", key: \"value\"}";
function myJSONParser(text) {
  const propRegex = new RegExp(/\w+(?=:)/g);
  const properties = text.match(propRegex)
  const valueRegex = new RegExp(/(?<=")[^,}]+/g);
  const vals = text.match(valueRegex);
  console.log(properties, vals);
  const obj = properties.map((prop, i) => ({prop: vals[i]}))
  return obj;


All of that is just to say, there is no need for the parser to be asynchronous.

Hope this helps

1 Like

you helped me a lot, thanks for your thorough replies!

1 Like