Fetch: what does response do?

I’m writing a React component that fetches data from an API and renders it.

My code looks like this:

class Menu extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      apiKey: "",
      name: "",
      description: "",
      price: 0
    };
  }

  componentDidMount() {
    console.log("mounted");
    fetch(
      "https://raw.githubusercontent.com/angel-design/ubiquitous-funicular/master/sandbox/response.json"
    )
      .then(fetched => {
        console.log("fetched");
      })
      .then(response => response.json())
      .then(json => {
        console.log("response logged");
      })
      .then(data =>
        this.setState({
          apiKey: data.apiKey,
          name: data.name,
          description: data.description,
          price: data.basePrice
        })
      )
      .then(stateSet => {
        console.log(this.state);
      })
      .catch(error => {
        console.log("error");
      });
  }

  render() {
    return <div>Hi</div>;
  }
}

My problem is:

  • The console log throws up an error after the component is mounted and the data fetched and before the response is logged.

  • What does the response promise do, and why is it creating an error?

Thank you for your time and help!

Instead of this:

console.log("error")

Do this:

console.error(error)

That’ll show the actual error you’re getting as an error in the console.

Also, the fetch API will not throw an exception if it encounters an HTTP error response (this is one major difference from axios). You need to check response.ok before slurping up the json data.

1 Like

Thank you so much! I updated the code:

componentDidMount() {
    console.log("mounted");
    fetch(
      "http://raw.githubusercontent.com/angel-design/ubiquitous-funicular/master/sandbox/response.json"
    )
      .then(fetched => {
        console.log("fetched");
      })
      .then(response => response.ok ? response.json(): console.log(response.statusText))
      .then(json => {
        console.log("response logged");
      })
      .then(data =>
        this.setState({
          apiKey: data.apiKey,
          name: data.name,
          description: data.description,
          price: data.basePrice
        })
      )
      .then(stateSet => {
        console.log(this.state);
      })
      .catch(error => {
        console.log(error);
      });
  }

The console log telling me that the error is [object Error] {} which is surprisingly difficult to google for. Do you know what I should be troubleshooting?

Error is an object, you’re just logging that error object. It has a field called message which contains the error text.

And the then calls work in a chain.

Fetch something, let's call it A
  Then use A, return B
  Then use B, return C
  Then use C, return D
  Catch any errors that have happened in the chain

(Edit: bearing that in mind, this link in the chain doesn’t pass the thing you want onto the next then: then(json => { console.log("response logged"); }), so the data argument in the next then will be undefined)

So if the response is not ok, and you’re catching the errors, then you need to throw an error.

.then(response => {
  if (response.ok) {
    return response;
  } else {
    throw new Error(response.statusText);
    // Promise is rejected and control jumps to
    // the nearest error handler (nearest catch)
  }
})

Then

.catch(error => console.log(error.message)
1 Like

Thank you! The error that is showing up is “Failed to fetch” on Chrome and “NetworkError when attempting to fetch resource.” on Firefox. Going into the network monitor, I see that my GET request to the json file has been blocked.

However, if I change the url to a different API (https://hn.algolia.com/api/v1/search?query=redux), I can access it fine. So it appears that the problem is that my json file on Github is being blocked.

Adding 'Accept': '*/*' to the header doesn’t do anything, nor does adding 'Content-Type': 'application/json' to the header. What should I do to fetch my file?

That sounds like the FCC challenge editor console, which is not suitable for real-world use. Chrome and Firefox should show you the actual error object on a red background.