29

I've just started to learn the Fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch

Here's a code snippet which I wrote to tinker around with it:

fetch('http://swapi.co/api/people/1')
  .then(function(response) {
    var json = response.json();

    console.log(json);
    // Expected : { "name": "Luke Skywalker","height": "1.72 m", ... } 
    // Get : Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
  }); 

I would have expected to get an JSON object out of response.json().

Similar to what you get when using JSON.parse().

Instead I get a promise object.

If I enlarge the promise chain like shown here ...

return response.json().then(function(json) {
      // process your JSON further
});

... then it works: Within the then method of the following promise it appears as json.

Why can't I retrieve the JSON data within the then() of the first promise?

Can anyone please explain what is going on here?

I would really much appreciate it.

cluster1
  • 4,968
  • 6
  • 32
  • 49
  • 3
    What most people are failing to mention is that by resolving as soon as you get headers, you can begin to do things with that information. Say if you get a 400 and a giant wall of text (not sure why that would be a thing), but you could immediately try a backup call or handle it, instead of wasting time to get the entire response body. – 1mike12 Aug 09 '17 at 18:42
  • I don't want to get down voted for proposing this answer... The object that was returned to you. (you named this "response") It has a datastream that it hasn't tapped into yet. Could be big or small, anyway. If are given a option of reading it and returning a json object. or you could check some header tag and deny the request completely. Ending the request here and now is as easy as throwing an error or returning. But to move forward with that datastream makes more since to use a Promise here. – user1529413 Aug 20 '21 at 19:26

1 Answers1

28

because response.json() returns another promise (which is within your function body)

https://developer.mozilla.org/en-US/docs/Web/API/Body/json

dee zg
  • 13,793
  • 10
  • 42
  • 82
  • 2
    Awesome. Thanks that at least explains the behaviour. And then I have to call another then for to get the result of the second promise. I just ask myself what's the benefit of all that nesting? – cluster1 Sep 11 '16 at 12:14
  • 8
    well, reasons are pretty straightforward: you use promises when you have async, potentially long runing operations. in your case there are 2 such actions: 1) fetch (which gets network resource which might take long time and reaolves it to Response once done) and 2) .json() which takes Response stream and resolves it to json object once its done (which also might be long). since both use promises you need .then() on both if you want to work with objects they resolve to. – dee zg Sep 11 '16 at 13:48
  • Get it. Because of your comment. :) Thanks a bunch ! – cluster1 Sep 11 '16 at 14:40
  • 4
    This is certainly unexpected, given by the number of questions regarding this behavior, and how other libraries handle ajax / rest api calls in general. It is an unnecessary hurdle for users to jump. – dshun Sep 07 '17 at 01:37
  • thanks for this, after trawling through dozens of stackoverflow posts this was the one that helped me realize what I needed to do for returning a new response obj – GPP Jun 26 '22 at 18:48