2

I am using body-parser, multer and express in my mern stack app. I need to upload a file as well as some text from the form. I am sending the post request as follows:

    function addPost(postdetail){
  axios.post('http://localhost:4000/blog',postdetail,{ headers:{
    "Content-Type": "multipart/form-data"
}}).then(res=>{
      dispatch({
        type:'ADD_DATA',
        payload:res.data,
       
      })
      
    }).catch(error=>{ 
      console.log(error)
    })
  }

When I add the header I get an empty object as the output of req.body. But when the multipart/form-data is not added I get other req.body but empty only for the file.

I have used the react hooks to set the state and appended the file using FormData. When the appended value is logged I get all the information of the uploaded file. So, I could know that the file is properly appended.

 const Addpost=()=> {
    const [title, settitle] = useState('')
    const [des, setdes] = useState('')
    const [file, setfile] = useState(null)
    const {addPost}=useContext(Globalcontext)
    
    const handleSubmit=(e)=>{
    e.preventDefault()
    const formData = new FormData()
    formData.append('file', file[0])
    console.log([...formData])
    
    const addedValue={
        title,
        des,
       formData
    }
    addPost(addedValue)
    
    settitle('')
    setdes('')
    setfile('')
    }
        return (
            <div>
                <form onSubmit={handleSubmit}>
                    <input type="text" name="title" value={title} onChange={(e)=>settitle(e.target.value)}/>
                    <input type="text" name="des" value={des} onChange={(e)=>setdes(e.target.value)}/>
                    <input type="file" name="file" onChange={(e)=>{setfile(e.target.files)}} />
                    <button type='submit' value='submit'>Add Post</button>
                </form>
            </div>
        )
    }
    
    export default Addpost

This is how I am using multer in the server side:

    const express=require('express')
    const multer=require('multer')
    const path=require('path')
    
    const storage = multer.diskStorage({
        destination: function(req, file, cb) {
            cb(null, __dirname+'/file/uploads/') 
          },
        filename:function(req,file,cb){
            cb(null,file.fieldname+path.extname(file.originalname))
        }
    })
const upload=multer({
    storage:storage
})

exports.addPost=(upload.any(),(req,res)=>{
                
    const post=new Blog()
    post.title=req.body.title
    post.des=req.body.des
    post.file = req.file
    post.save((err,doc)=>{
        if(!err){
            res.send(doc)
        }
        else{
            console.log(err)
        }
    })
    console.log(req.body)
})

I think the problem is only with the server-side where I am trying to upload the file using multer. After I have used the header in the axios post request I am not able to insert any information to the mongoose and I get {} for consoling req.body and other fields are undefined.

1 Answers1

1

Since you are using multer.any(), an array of files will be stored in req.files (see https://www.npmjs.com/package/multer#any).

In your case you can simply use multer.single() as you're uploading a single image - the file will then be available under req.file, rest of the form data will be available under req.body:

exports.addPost=(upload.single('file'),(req,res)=> { ... });
eol
  • 23,236
  • 5
  • 46
  • 64
  • I am still getting the empty object: { } when I console.log(req.body) and req.file is undefined with upload.single – october cms Jul 17 '20 at 07:06
  • I've answered a similar question recently, the form-upload on the client was not correct. Check this -> https://stackoverflow.com/a/62865341/3761628 Maybe it helps :) – eol Jul 17 '20 at 07:08
  • No didn't work :( When I add the header in axios post request I am not able to get any form data. Can you please check the way I am sending the text as well as file to the addPost method. – october cms Jul 17 '20 at 07:54