const key = '618479acc2ef5ba8018516ac'
function UserPost1 () {
const [post, setPost] = useState(['']);
const handleExpandClick = () => {
setExpanded(!expanded);
};
useEffect(() =>{
axios.get('https://dummyapi.io/data/v1/post' , { headers: { 'app-id': key } })
.then(res => {
setPost(res.data.data)
console.log(res)
})
.catch(err =>{
console.log(err)
})
},[]);
return(
<div className="Post-style">
{post.map(post =>(
<Box sx={{ flexGrow: 1 }}>
<Grid container rowSpacing={0} columnSpacing={{ xs: 1, sm: 2, md: 2, lg: 2 }} >
<Grid
container
direction="row"
justifyContent="center">
<Grid item xs={4} sm={12} md={6} lg={4}>
<div className="card-Style">
<Card sx={{ width: 355}} style={{backgroundColor: "aquamarine"}} >
<CardHeader
avatar={
<Avatar
src={post.owner.picture}
/>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={post.owner.firstName " " post.owner.lastName}
subheader={post.publishDate}
/>
<CardMedia
component="img"
height="194"
image={post.image}
alt="Paella dish"
backgroundcolor="blue"
/>
<CardContent>
<Typography variant="body2" color="text.secondary">
{post.text}
<br></br>
{post.likes}
<br></br>
{post.tags}
</Typography>
</CardContent>
</Card>
</div>
</Grid>
</Grid>
</Grid>
</Box>
))}
</div>
)
}
export default UserPost1;
When im run this code i cant get the data from API using Axios, it says error cannot read properties of undefined (reading 'picture'). I tried to catch the error but it does not show in console log. How do i solve this problem.
should i make the axios to wait until it gets the data API or make it to false. What should i do, its my first time with API.
CodePudding user response:
Somehow, the picture property is missing inside the owner object.
Add optional chaining before picture:
<CardHeader
avatar={
<Avatar
src={post.owner?.picture}
/>
}
...
CodePudding user response:
Render your post component after complete async query and set state value. Use condition rendering and change default state value from [''] to null.
If your component has a specific height and width, then create a placeholder with the same values.
To exclude layout jumps during query execution, show a placeholder. Show the placeholder while the request is running, and after the request is complete and the value is set to the state, show the post component. Good luck!
// change default useState value
const [post, setPost] = useState(null);
// add condition rendering
{post ? post.map(post => (
<Box sx={{ flexGrow: 1 }}>
<Grid container rowSpacing={0} columnSpacing={{ xs: 1, sm: 2, md: 2, lg: 2 }} >
<Grid
container
direction="row"
justifyContent="center">
<Grid item xs={4} sm={12} md={6} lg={4}>
<div className="card-Style">
<Card sx={{ width: 355 }} style={{ backgroundColor: "aquamarine" }} >
<CardHeader
avatar={
<Avatar
src={post.owner.picture}
/>
}
action={
<IconButton aria-label="settings">
<MoreVertIcon />
</IconButton>
}
title={post.owner.firstName " " post.owner.lastName}
subheader={post.publishDate}
/>
<CardMedia
component="img"
height="194"
image={post.image}
alt="Paella dish"
backgroundcolor="blue"
/>
<CardContent>
<Typography variant="body2" color="text.secondary">
{post.text}
<br></br>
{post.likes}
<br></br>
{post.tags}
</Typography>
</CardContent>
</Card>
</div>
</Grid>
</Grid>
</Grid>
</Box>
)) : <div> PLACEHOLDER </div>}