I'm trying to create a small social network in which we can send posts (with or without images).
I manage to create posts without an image (just text), it works very well, but as soon as I add an image to my form and submit the form, it is impossible to find the image. Normally it should be saved in the "images" folder but it is always empty.
I am using multer to do that, here is my code :
My form component :
const WhatsUpForm = ({ className, id, name, placeholder }) => {
const [inputValue, setInputValue] = useState("");
const inputHandler = (e) => {
setInputValue(e.target.value);
};
const submitHandler = async (e) => {
e.preventDefault();
const post = {
author_firstname: JSON.parse(localStorage.getItem("user")).user_firstname,
author_lastname: JSON.parse(localStorage.getItem("user")).user_lastname,
message: inputValue,
date_creation: dayjs().format(),
image_url: ""
};
// POST request
await POST(ENDPOINTS.CREATE_POST, post);
// document.location.reload()
};
return (
<form className={className} onSubmit={submitHandler} method="POST" action="/api/post" enctype="multipart/form-data">
<input className="testt" type="text" id={id} name={name} placeholder={placeholder} required value={inputValue} onChange={inputHandler}/>
<div className="icons_container">
<input type="file" name="image" id="image" className="icons_container__add_file" />
<label for="image">
<FontAwesomeIcon icon={faImages} />
</label>
<button type="submit" className="icons_container__submit">
<FontAwesomeIcon icon={faPaperPlane} />
</button>
</div>
</form>
);
};
My routes and the multer's code :
const multer = require("multer");
const path = require("path");
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, "../images");
},
filename: (req, file, callback) => {
console.log("multer");
console.log("file :", file);
callback(null, Date.now() path.extname(file.originalname));
},
});
const upload = multer({ storage: storage });
// Post CRUD
router.get("/", auth, postCtrl.getAllPosts);
router.post("/", auth, upload.single("image"), postCtrl.createPost);
router.delete("/:id", auth, postCtrl.deletePost);
router.put("/:id", auth, postCtrl.updatePost);
console.log("multer") is not trigger, and when i look the payload in network tab in my browser, i don't see any images.
And finally, my controller for createPost function :
exports.createPost = (req, res, next) => {
let { body } = req;
delete(req.body.image_url)
body = {
...body,
likes: "",
};
const sql = "INSERT INTO posts SET ?";
db.query(sql, body, (err, result) => {
if (err) {
res.status(404).json({ err });
throw err;
}
res.status(200).json({ msg: "Post added..." });
});
};
For now, i don't want to put the image's URL in my SQL DB, i just want to save the image in my images folders. I have verified the path (../images) and it's coorect. How do I save the image in my image folder?
CodePudding user response:
I don't see the file data gets sent to server from your POST request.
// object post doesn't have the file data
await POST(ENDPOINTS.CREATE_POST, post);
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Consider using FormData
const submitHandler = async (e) => {
e.preventDefault();
const post = new FormData();
// non form data
formData.append("author_firstname", JSON.parse(localStorage.getItem("user")).user_firstname);
...
// form data
formData.append("image", document.getElementById("image").files[0]);
...
// POST request
await POST(ENDPOINTS.CREATE_POST, post);
// document.location.reload()
};
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>