I am able to fetch the data from API endpoint but am not able to render it to the screen.
This is my App.js component.
function App() {
const [data, setData] = useState([]);
const [img, setImg] = useState([]);
useEffect(() => {
fetchData(setData);
}, []);
async function fetchImage(name) {
const requestOptions = {
method: "GET",
redirect: "follow",
};
await fetch(
`https://avatars.dicebear.com/v2/avataaars/${name}.svg?options[mood][]=angry`,
requestOptions
)
.then((response) => response.text())
// .then((text)=>setImg(text))
.catch((error) => console.log("error", error));
}
return (
<div className="App">
{data.map((details) => {
return (
<Card
key={details.id}
email={details.email}
name={details.name}
image={fetchImage(details.username)}
phone={details.phone}
website={details.website}
company={details.company.name}
/>
);
})}
</div>
);
}
This is my card component.
export default function Card(props) {
return (
<Box
w="70vw"
h="250px"
borderWidth="1px"
borderColor={"black"}
overflow="hidden"
m="2vh auto"
display={"flex"}
flexDir="row"
color="black"
>
<Box>
<Image
w="20vw"
h="250px"
src={props.image}
bg="gray"
/>
</Box>
<Box display='flex' flexDirection={'column'} alignItems='flex-start' ml='2vw' fontSize={'lg'}>
<Box fontSize={'3xl'} mb='2vw'>{props.name}</Box>
<Box><strong>Email: </strong>{props.email}</Box>
<Box><strong>Phone: </strong>{props.phone}</Box>
<Box><strong>Company: </strong>{props.company}</Box>
<Box><strong>Website: </strong>{props.website}</Box>
<Box><strong>Address: </strong>{props.address}</Box>
</Box>
</Box>
I figured out is returning promise instead of fetched data. If I uncomment the setImg promise, images are fetched continuously but still not rendering. Please help. Thanks in advance.
CodePudding user response:
I hope below code help you.
App.js:
function App() {
const [data, setData] = useState("");
useEffect(() => {
fetchData(setData);
}, []);
return (
<div className="App">
{data.map((details) => {
return (
<Card
key={details.id}
email={details.email}
name={details.name}
username={details.username} // <=== Change image prop to username prop
phone={details.phone}
website={details.website}
company={details.company.name}
/>
);
})}
</div>
);
}
Card component:
export default function Card(props) {
const imgURL = `https://avatars.dicebear.com/v2/avataaars/${props?.name}.svg?options[mood][]=angry`
return (
<Box
w="70vw"
h="250px"
borderWidth="1px"
borderColor={"black"}
overflow="hidden"
m="2vh auto"
display={"flex"}
flexDir="row"
color="black"
>
<Box>
<Image
w="20vw"
h="250px"
src={imgURL} //<=== This is src img
bg="gray"
/>
</Box>
<Box display='flex' flexDirection={'column'} alignItems='flex-start' ml='2vw' fontSize={'lg'}>
<Box fontSize={'3xl'} mb='2vw'>{props.name}</Box>
<Box><strong>Email: </strong>{props.email}</Box>
<Box><strong>Phone: </strong>{props.phone}</Box>
<Box><strong>Company: </strong>{props.company}</Box>
<Box><strong>Website: </strong>{props.website}</Box>
<Box><strong>Address: </strong>{props.address}</Box>
</Box>
</Box>
CodePudding user response:
You'r not using the await fetch(...)
result
In general, don't mix await
and then
use one or another
Plus, if api returns image data, you should not convert it to text, but to blob and use URL.createObjectURL
to create a correct url
const response = await fetch(
`https://avatars.dicebear.com/v2/avataaars/${name}.svg?options[mood][]=angry`,
requestOptions
)
const blob = await response.blob();
return URL.createObjectURL(blob)
Or use the api url directly if you can:
return `https://avatars.dicebear.com/v2/avataaars/${name}.svg?options[mood][]=angry`;
But you should use state to store the generated URLs. This code could be used in your fetchData()
function and add the imageUrl to each item to not refetch on each render