how do I deal with getting back null in fetch requests? Eventually the request goes through but for some reason it gives back bunch of nulls before getting the data. could this be something wrong with my code or is this just normal fetch behavior?
Fetch setup
const [subDomains, setSubDomains] = useState(null)
const [website, setwebsite] = useState("twitter.com")
useEffect(() => {
async function fetchData() {
const response = await fetch("api_url="+website,{
headers: {
"X-Api-Key": "hidden"
}
})
const data = await response.json()
const subdomains = data["ContributingSubdomain"]
const convertedsubdomains = Object.keys(subdomains)
let otherdomains = []
for(let i=0; i < convertedsubdomains.length; i++) {
const subdomains2 = data.ContributingSubdomain[i]["DataUrl"]
otherdomains.push(subdomains2)
}
setSubDomains(otherdomains)
}
fetchData()
}, [website])
Then the subDomains prop is passed on to a component as domains
const SubDomains = ({domains}) => {
return (
<div>
<div>
{domains.forEach((e) =>
<h2>{e}</h2>
)}
</div>
</div>
)
}
export default SubDomains
I get an error saying TypeError: Cannot read properties of null (reading 'forEach')
When I console.log(domains), I see that I get a bunch of nulls before getting the actual data, which I assume is causing the above error. but I don't know what I'm doing wrong when requesting the data and passing it on
I really don't know why it returns keeps returning null before getting back the response, but since you initialized subDomains to null it'll return null for the very first render. But to fix the
TypeError: Cannot read properties of null (reading 'forEach')
all you have to do is check if domains has a value before mapping the values.
You can change this line:
{domains.forEach((e) =>
<h2>{e}</h2>
)}
to:
{domains?.forEach((e) =>
<h2>{e}</h2>
)}
Notice I added a question mark before domains. It's the optional chaining operator (?.). It enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.
Also, why not map the values, rather than forEach. Like so:
{domains?.map((domain, index) =>
<h2 key={index}>{domain}</h2>
)}
If there are IDs that come along with the domains, then you can use those as the key instead of the index.