Fix ReactJS Code Error While Postman Shows Success?

I’m trying to fetch data from an API in my ReactJS code, but while it works perfectly in Postman with a 200 response, my code keeps throwing an error. I’ve set up the fetch request and am handling response status, but still can’t figure out why it’s failing in React. Here is my code

Error Code:

codeimport React, {Component} from "react"; 

const urlEndPoint = myEndPoint => "https://api.github.com/users/adhishlal"

export default class Categories extends Component {
constructor(props) {
super(props)
this.state = {
requestFailed: false
}
}

componentDidMount() {


fetch(urlEndPoint(this.props.myEndPoint))


.then(response => {
if (!response.ok) {
throw Error(response.statusText)
}
return response
})

.then(d => response.json())


.then(response => {
this.setState({
responseData: d
})
}, () =>
{
this.setState({
requestFailed: true
})
})


}

render() {

//If request is failed
if(this.state.requestFailed)
{
return <div>Request Failed</div>
}

//Waiting for data to load from Zoho
if(!this.state.responseData)
{
return <div>Loading...</div>
}

//Finally populate the data when loaded


var indents = [];
for (var i = 0; i < 10; i++) {

indents.push(

<div className="col-sm-4 col-xs-12"><div className="cr-openings">
<p className="no-margin font-color-lightGrey no-of-openings">{i+1}</p><p className="catg-openings font-color-white">{this.state.responseData.name}</p>
<p className="font-color-lightGrey city-openings no-margin">Bangalore , Chennai , Delhi NCR , Hyderabad , Mumbai</p>
</div>
</div>

);
}


return (
<section className="dotted">
<div className="dotted-bg-dark">
<div className="container padding-80-0">
<div className="row m-b-30">
{indents}
</div>
</div>
</div>
</section>
);




}
}

Explanation of Issues:

  1. then(d => response.json()) Misuse:
    • d => response.json() is incorrect because the variable d should be the response from the previous .then. The correct syntax is response => response.json().
  2. State Initialization:
    • responseData was not initialized in this.state, which may cause issues in some cases. Initializing it as null will prevent any potential undefined errors during rendering.
  3. Component Structure and Error Handling:
    • It’s better to use .catch() to handle any errors at the end of the promise chain instead of using the second argument in .then.
  4. Unnecessary Function Wrapping in then:
    • Instead of then(response => {...}, () => {...}), separating the error handler into .catch() is preferred for better readability.

Corrected Code:

codeimport React, { Component } from "react";

const urlEndPoint = myEndPoint => `https://api.github.com/users/${myEndPoint || "adhishlal"}`;

export default class Categories extends Component {
constructor(props) {
super(props);
this.state = {
requestFailed: false,
responseData: null, // Initialize responseData as null
};
}

componentDidMount() {
// Call API endpoint with optional myEndPoint prop
fetch(urlEndPoint(this.props.myEndPoint))
.then(response => {
if (!response.ok) {
throw Error(response.statusText); // Throw an error if response is not ok
}
return response.json(); // Parse JSON if response is ok
})
.then(data => {
// Set the fetched data in state
this.setState({
responseData: data,
});
})
.catch(() => {
// Handle errors by setting requestFailed to true
this.setState({
requestFailed: true,
});
});
}

render() {
const { requestFailed, responseData } = this.state;

// If request failed
if (requestFailed) {
return <div>Request Failed</div>;
}

// Waiting for data to load
if (!responseData) {
return <div>Loading...</div>;
}

// Populate the data when loaded
const indents = [];
for (let i = 0; i < 10; i++) {
indents.push(
<div className="col-sm-4 col-xs-12" key={i}>
<div className="cr-openings">
<p className="no-margin font-color-lightGrey no-of-openings">{i + 1}</p>
<p className="catg-openings font-color-white">{responseData.name}</p>
<p className="font-color-lightGrey city-openings no-margin">Bangalore, Chennai, Delhi NCR, Hyderabad, Mumbai</p>
</div>
</div>
);
}

return (
<section className="dotted">
<div className="dotted-bg-dark">
<div className="container padding-80-0">
<div className="row m-b-30">
{indents}
</div>
</div>
</div>
</section>
);
}
}

Key Changes and Explanations:

  1. Corrected the .then() chain:
    • Changed .then(d => response.json()) to .then(response => response.json()).
  2. Error Handling with .catch():
    • Added .catch() at the end of the promise chain for better error handling.
  3. responseData State Initialization:
    • Initialized responseData in this.state to null to avoid potential undefined issues during the initial render.
  4. Key Property in the Loop:
    • Added a key={i} to each element in indents to ensure unique keys, which helps React efficiently update the DOM.
  5. myEndPoint in URL:
    • Used a template literal to pass myEndPoint dynamically, with a fallback to "adhishlal" if myEndPoint is not provided.

Related blog posts