I am currently working on a project that involves a React frontend and a Spring Boot backend. As part of this project, I need to create events that include both details and flyers. When saving an event, I send the flyer as a file to the backend, where it is converted into a byte array and successfully saved.
Now, I am facing a challenge with displaying the image in the frontend. Specifically, I need to retrieve the byte array from the backend and display the image on the frontend. However, I have been unable to do so thus far.
Here is the code :
export default function EditEvent() {
const { id } = useParams();
let navigate = useNavigate();
const [event, setEvent] = useState({
eventName: "",
eventType: "",
eventLocationType: "",
});
const [location, setLocation] = useState("");
const [startTime, setStartTime] = useState(moment());
const [endTime, setEndTime] = useState(moment());
const [selectedImage, setSelectedImage] = useState(undefined);
const [imageUrl, setImageUrl] = useState(null);
const { eventName, eventType, eventLocationType } = event;
useEffect(() => {
loadEvent();
}, []);
const loadEvent = async (e) => {
const result = await axios.get(
`http://localhost:8080/api/event/getEvent/${id}`
);
console.log(result.data);
setEvent(result.data);
setLocation(result.data.location);
setStartTime(moment(result.data.startTime, "YYYY-MM-DDTHH:mm"));
setEndTime(moment(result.data.endTime, "YYYY-MM-DDTHH:mm"));
console.log(result.data.eventFlyer)
const byteArray = result.data.eventFlyer;
const blob = new Blob([byteArray], { type: "image/png" });
console.log(blob)
const imageUrl = URL.createObjectURL(blob);
console.log(imageUrl);
const img = new Image();
img.onload = function () {
console.log("Image loaded successfully.");
};
img.onerror = function (error) {
console.log("Error loading image.", error);
};
img.src = imageUrl;
};
useEffect(() => {
if (selectedImage) {
setImageUrl(URL.createObjectURL(selectedImage));
}
}, [selectedImage]);
return(
<FormLabel disabled={true} align="left" sx={{ paddingBottom: "10px" }}>
Event Flyer<span>(Optional)</span>
</FormLabel>
<div style={{ textAlign: "left", paddingBottom: "30px" }}>
<input
accept="image/*"
type="file"
id="select-image"
style={{ display: "none" }}
name="eventFlyer"
onChange={(e) => setSelectedImage(e.target.files[0])}
/>
<label htmlFor="select-image">
<Button component="span" color="inherit">
<CloudUploadOutlinedIcon sx={{ paddingRight: "10px" }} />
Click to browse
</Button>
</label>
{imageUrl && selectedImage && (
<Box mt={2} textAlign="center">
<div>Image Preview:</div>
<img src={imageUrl} alt={selectedImage.name} height="100px" />
</Box>
)}
</div>
)
So here I'm getting the console.log as ,
Error loading image. Event {isTrusted: true, type: 'error', target: img, currentTarget: img, eventPhase: 2, …}isTrusted: truebubbles: falsecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: nulldefaultPrevented: falseeventPhase: 0returnValue: truesrcElement: nulltarget: nulltimeStamp: 15488456.5type: "error"[[Prototype]]: Event
I just checked whether the recived byte[] is valid or not using Base64 to image converter. It also shows that byte[] is valid and shows the image correctly.
UPDATE
This the result.data
showing in the console.
I would greatly appreciate any suggestions or code examples that can help me overcome this issue and display the image correctly. Thank you in advance for your assistance.
The JSON response that you obtained from fetch
is in Base64 encoding instead of raw byte array. You can consider displaying the image directly instead by prepending the result with data:image/jpeg;base64,
, sample below:
const [imageSrc, setImageSrc] = useState('');
const loadEvent = async (e) => {
const result = await axios.get(
`http://localhost:8080/api/event/getEvent/${id}`
);
setImageSrc('data:image/jpeg;base64,' + result.data.eventFlyer)
};
<img src={imageSrc} />