I have a react component that gets data from an API end point. For the purposes of debugging when I call the API I log the result of the API call to the console and it looks like this:
The problem I have is that when I try to render the BreadCrumbLinks Property in my component I get this error:
TypeError: Cannot read properties of undefined (reading ‘map’)
at BreadCrumbHeader
I am getting an “Undefined” error, but I know that the data is present because I can read and render all of the other fields (for example BreadCrumbBgImage
).
Also, if I comment out the map/loop the rest of the data is displayed correctly when the page loads. Then if I uncomment it out and save the file the data for the map/loop now shows correctly.
I can only assume that the code is trying to render the contents of the loop before it has been loaded.
This is what the code for the component looks like:
import React, { useState, useEffect } from 'react';
import API from "../../API";
import { useLocation } from 'react-router-dom';
import { BreadCrumbTitleSection, SubtitleSection, Subtitle } from './breadCrumbHeaderStyle';
import { Breadcrumb } from 'react-bootstrap';
function BreadCrumbHeader() {
const location = useLocation();
const [breadCrumbData, setBreadCrumbData] = useState([]);
const getBreadCrumbData = async () => {
const breadCrumbHeaderResponse = await API.fetchBreadCrumbHeader(location.pathname);
setBreadCrumbData(breadCrumbHeaderResponse);
console.log("OUT-PUT-OF-API-CALL");
console.log(breadCrumbHeaderResponse);
console.log("END-OF-OUT");
};
useEffect(() => {
getBreadCrumbData();
}, [location.pathname]);
return (
<div>
<BreadCrumbTitleSection backgroundUrl={breadCrumbData.BreadCrumbBgImage}>
<div className="container">
<div className="row no-gutters">
<div className="col-xs-12 col-xl-preffix-1 col-xl-11">
<h1 className="h3 text-white">{breadCrumbData.BreadCrumbTitle}</h1>
<Breadcrumb>
{breadCrumbData.BreadCrumbLinks.map(breadCrumbLink => (
<Breadcrumb.Item href={breadCrumbLink.LinkUrl} key={breadCrumbLink.Id} active={breadCrumbLink.IsActive}>
{breadCrumbLink.LinkText}
</Breadcrumb.Item>
))}
</Breadcrumb>
</div>
</div>
</div>
</BreadCrumbTitleSection>
<SubtitleSection>
<Subtitle> {breadCrumbData.SubTitle}</Subtitle>
</SubtitleSection>
</div>
);
}
export default BreadCrumbHeader;
Can anyone explain what is going on here and how I can solve i?
Advertisement
Answer
You are trying to map data before its fetched, so its an empty array (initial value of breadCrumbData state). You should use optional chaining:
{breadCrumbData?.BreadCrumbLinks?.map(breadCrumbLink =>