vincent05996
vincent05996

Reputation: 171

Node / React : I can't upload an image with my post with multer

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?

Upvotes: 0

Views: 237

Answers (1)

spiritwalker
spiritwalker

Reputation: 2257

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);

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()
  };

Upvotes: 1

Related Questions