18

I am trying to use fetch api to bring back some data, however am unable to map it to the console once I have retrieved it.

fetch('http://jsonplaceholder.typicode.com/users', { 
  method: 'GET'
}).then(function(response) {
  console.log(response)
  response.forEach(i => console.log(i.name));
}).catch(function(err) {
  console.log(`Error: ${err}` )
});

The error i get is

response.map is not a function

so I tried to parse the response,(ie var data=JSON.parse) which did not work, with the error

SyntaxError: Unexpected token o in JSON at position 1"

Interestingly, when doing the same thing with a XMLHttp request, I was required to parse it, so I would also be interested to know why the difference between these two methods of retrieving the data.

If anyone could point me in the right direction, I would be really grateful.

Mike Cluck
  • 31,869
  • 13
  • 80
  • 91
matt-p
  • 1,017
  • 2
  • 12
  • 21

3 Answers3

33

The Fetch API returns a response stream in the promise. The response stream is not JSON, so trying to call JSON.parse on it will fail. To correctly parse a JSON response, you'll need to use the response.json function. This returns a promise so you can continue the chain.

fetch('http://jsonplaceholder.typicode.com/users', { 
  method: 'GET'
})
.then(function(response) { return response.json(); })
.then(function(json) {
  // use the json
});
Steven Lambert
  • 5,571
  • 2
  • 29
  • 46
  • 4
    I know this answer was given in 2016... but here it is 2020, and the MDN docs still says that .json() is an experimental and under-supported method. Making using this a nightmare with broad compatibility (especially in the mobile market). – IncredibleHat Feb 11 '20 at 20:59
  • 1
    @IncredibleHat no warning there now. For reference, see https://caniuse.com/mdn-api_response_json – Phil Nov 23 '21 at 03:10
  • @Phil nice, about time! Thanks for the heads up and update to this answer as well. – IncredibleHat Nov 24 '21 at 19:33
6

Understanding promises is key to using the fetch API.

At the time you're trying to parse your response and loop through it, the response is actually just a promise. In order to utilize the contents of the actual response from the request, you'll have to do some promise chaining.

fetch('http://jsonplaceholder.typicode.com/users').then(function(response) {
  // response.json() returns a promise, use the same .then syntax to work with the results
  response.json().then(function(users){
    // users is now our actual variable parsed from the json, so we can use it
    users.forEach(function(user){
      console.log(user.name)
    });
  });
}).catch(err => console.error(err));
shamsup
  • 1,952
  • 14
  • 18
3

It appears that you might be accessing the json incorrectly. You could try calling response.json() instead.

fetch('http://jsonplaceholder.typicode.com/users', {
  method: 'GET'
}).then((response) => {
  response.json().then((jsonResponse) => {
    console.log(jsonResponse)
  })
  // assuming your json object is wrapped in an array
  response.json().then(i => i.forEach(i => console.log(i.name)))
}).catch((err) => {
  console.log(`Error: ${err}` )
});

This example is structured to match your example, but ideally, you would return response.json() on that first .then block and proceed on the next block. Here is a similar example that proceeds on the next block.

In your particular case, you can view the Fetch API as a json aware wrapper for "XMLHttpRequest"s. Main differences being that the Fetch API is simpler, functional-like, and has convenience methods. David Walsh does a reasonable comparison in his blog post, which I recommend you take a look at. Plain "XMLHttpRequest"s just pass you whatever string was sent back from the server, it has no idea it could be JSON, and thus leaves it to the user to parse the response whatever way they see fit.

m-a-r-c-e-l-i-n-o
  • 2,622
  • 18
  • 26
  • 1
    `response.json()` returns a promise, so you cannot just call forEach on it. Something more along the lines of `response.json().then(function(users){users.forEach(function(user){console.log(user.name)})` – shamsup Jun 06 '16 at 18:12
  • 1
    Sorry about that. Edited. @ShamSUP thanks for pointing it out! – m-a-r-c-e-l-i-n-o Jun 06 '16 at 18:22