I need some help displaying my images on my react website. Currently, I am able to input the image into the upload folder and the PostgreSQL database, but I have no way of displaying it. I’ve tried using hooks with fetch to bring my data over, this has not caused any error so it might be my API is wrong or route is wrong. I am not sure and need some help. Please.
Server.Js - Backend folder
app.use(cors({
origin:true,
methods:["POST","GET", "PUT", "DELETE"],
credentials:true
}));
app.use(express.json());
app.use('/uploads', express.static(path.resolve(__dirname, './uploads')));
const fileStorageEngine = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./uploads");
},
filename: function (req, file, cb) {
cb(null, new Date().valueOf() + '_' + file.originalname);
},
});
const fileFilter = (req, file, cb) => {
if(file.mimetype === 'image/jpeg' ||
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/gif')
{
cb(null, true);
}
else{
cb(null, false);
console.log("Invalid file type.")
}
}
const upload = multer({
storage: fileStorageEngine,
limits:{
fileSize: 1024 * 1024 * 5
},
fileFilter:fileFilter
});
app.post('/api/image', upload.single('image'), (req, res) => {
console.log(req.file);
const { filename, mimetype, size } = req.file;
const filepath = req.file.path;
pool.query("INSERT INTO image_files (filename, filepath, mimetype, size) VALUES ($1, $2, $3, $4)", [filename, filepath, mimetype, size])
.then(() => res.json({ success: true, filename }))
.catch(err => res.json({ success: false, message: 'upload failed', stack: err.stack }));
});
app.get("/api/image/:filename", async (req, res) => {
const { filename } = req.params;
pool.query("SELECT * FROM image_files WHERE id = $1", [filename])
.then(images => {
if (images[0]) {
const dirname = path.resolve();
const fullfilepath = path.join(dirname, images[0].filepath);
return res.type(images[0].mimetype).sendFile(fullfilepath);
}
return Promise.reject(new Error('Image does not exist'));
})
.catch(err => res.status(404).json({success: false, message: 'not found', stack: err.stack}),
);
});
Upload.js - Front end folder
import { toast } from "react-toastify";
import React, { useEffect, useState } from "react";
const Upload = () => {
const [file, setFile] = useState();
const [uploadStatus, setUploadStatus] = useState("");
const [image, setImage] = useState('');
const fileChangeHandler = (e) => {
setFile(e.target.files[0]);
};
const onSubmitHandler = (e) => {
e.preventDefault();
const formData = new FormData();
formData.append("image", file);
fetch("http://localhost:5000/api/image", {
method: "POST",
body: formData,
headers: {
'Accept': "multipart/form-data",
},
credentials: "include",
})
.then((res) => res.json())
.then((res) => {
console.log("File Sent Successful");
toast.success("File Sent Successfully!");
setUploadStatus(res.msg);
})
.catch((err) => {
console.log(err.message);
});
};
useEffect(() => {
fetch("http://localhost:5000/api/image", {
method: "GET",
headers: {
"Content-Type": "application/json, charset=UTF-8",
'Accept': "application/json, text/html",
},
credentials:'include'
})
.then (data => data.json())
.then ((data) =>{
console.log(data)
setImage('http://localhost:5000/' + data.image)
console.log(image)
})
});
return (
<div>
<form id="form" onSubmit={onSubmitHandler} encType="multipart/form-data">
<input id="myfilefield" type="file" onChange={fileChangeHandler} />
<hr></hr>
<button className="btn btn-success" type="submit">
Upload
</button>
<h2> {uploadStatus} </h2>
{image && <img src={image} alt="img" />}
</form>
</div>
);
};
export default Upload;
Basically What I’m seeing