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

Time:10-28

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>

  • Related