I am new to React JS and still struggling in mastering a few concepts.
I am trying to do error handling for my code and only display the API response only after the Fetch is complete.
Below I have my code which is what I have done.
import React, { useState, useEffect } from "react";
function Transaction({ response }) {
const [transaction, setTransaction] = useState([]);
const token = "2c506c6b-d880-36bb-bdba-a035d1464b35";
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`
},
};
useEffect(() => {
fetch(
"https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/transaction/5KISDW53",
requestOptions
)
.then((response) => response.json())
.then((data) => setTransaction(data));
}, []);
// console.log(transaction.result.details[0].vouchers[0].result);
return (
<>
<div>
Hello
<b>Transaction Status:</b> {transaction.status} <br />
</div>
</>
);
}
export default Transaction;
And below is how I am trying to do some clean error handling. Can someone help me, or at least refer me to where I can learn how to do this properly.
import React, { useState, useEffect } from "react";
function Transaction({ response }) {
const [transaction, setTransaction] = useState([]);
const token = "2c506c6b-d880-36bb-bdba-a035d1464b35";
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
function handleErrors(response) {
if (!response.ok) {
throw Error(response.statusText);
}
return response;
}
useEffect(() => {
fetch(
"https://api.flash-internal.flash-group.com/ecommerceManagement/1.0.0/api/transaction/5KISDW53",
requestOptions
)
.then(handleErrors)
.then((response) => console.log("ok"))
.catch((error) => console.log(error))
.then((response) => response.json())
.then((data) => setTransaction(data));
}, []);
// console.log(transaction.result.details[0].vouchers[0].result);
return (
<>
<div>
<b>Transaction Status:</b> {transaction.status} <br />
</div>
</>
);
}
export default Transaction;
An issue I see is that you are implicitly returning the void result of a console log in the Promise chain, so later thenables aren't receiving the unpacked JSON response value.
useEffect(() => {
fetch(
"......",
requestOptions
)
.then(handleErrors)
.then((response) => console.log("ok")) // <-- returns undefined!
.catch((error) => console.log(error))
.then((response) => response.json()) // <-- can't call `json()` of undefined!
.then((data) => setTransaction(data));
}, []);
It seems like you are asking about the fetch processing. I would suggest checking for the ok response before returning the json, right there inline. If you want to conditionally wait to display any fetched content then use a loading state.
Example:
function Transaction({ response }) {
const [loading, setLoading] = useState(true);
const [transaction, setTransaction] = useState();
const requestOptions = {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
};
useEffect(() => {
setLoading(true);
fetch(
".....",
requestOptions
)
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
return response.json();
})
.then((data) => {
setTransaction(data)
})
.catch((error) => {
console.log(error)
})
.finally(() => {
setLoading(false);
});
}, []);
if (loading) {
return null; // or loading spinner/etc
}
return (
<>
{transaction
? (
<div>
<b>Transaction Status:</b> {transaction.status} <br />
</div>
)
: <div>No transaction data</div>
}
</>
);
}
If you want to display any errors then add some error state and some conditional rendering logic to display it, similar to the transaction state.
you can use conditional rendering in react.
return (
{
transaction.length === 0 ? <></> :
<>
<div>
<b>Transaction Status:</b> {transaction.status} <br />
</div>
</>
}
)
you can use loading or anything that you want instead of <></> and also any other proper condition for data existence.