1

I'm making image uploader,BE side works fine I tested route in the postman and it uploaded the img as its supposed to do.

Route itself

app.post('/upload/:id',(req,res) => {
upload(req, res, (err) => {
    if (err) {
        console.log('--------err', err);
    } else {
        if (req.file === undefined) {
            res.json({
                msg:"Error:No file selected"
            })
        } else {
            console.log('--------req.file', req.file);
            Users.update({
                avatar : req.body.avatar
            },
                {where : {
                    id  : req.params.id
                    }})
            res.json({
                msg : "File uploaded",
                file : `uploads/${req.file.filename}`
            })
        }
    }
})
})
//Uploads

This is place where Pictures must be saved(Local folder)

 const storage = multer.diskStorage({
        destination : './uploads',
        filename : (req, file, cb) => {
            cb(null,file.fieldname + "-" + Date.now() + ".jpeg" +
            path.extname(file.originalname));
        }
    })

// Init upload

const upload = multer({
    storage : storage,
    fileFilter : (req,file,cb) => {
        checkFileType(file,cb)
    }
}).single('avatar')

// Check file type

This function checks type of file

 const checkFileType = (file,cb) => {
        // Allowed extensions
        const fileTypes = /jpeg|jpg|png|gif/;
        //Check extensions
        const extname = fileTypes.test( path.extname(file.originalname).toLowerCase())
        //Check mimeType
        const mimetype = fileTypes.test(file.mimetype)
    
        if(mimetype && extname) {
            return cb(null,true);
        } else {
            return cb("Error: Images Only")
        }
    
    }

As I said in the start in postman this route works just perfectly,But the Frontend is the main problem.

Here is how I'm sending request from the ReactJS Component

    const fileselectedHandler = (event: any): void => {
    newImg(URL.createObjectURL(event.target.files[0]))
  }

  const fileuploadHandler = () : void => {
    const data = new FormData()
    data.append('avatar', img)
    axios.post(`http://localhost:4000/upload/${match.params.userId}`,{
      avatar : data
    })
      .then(res => {
        console.log(res)
      })
      .catch(err =>
        console.log('--------err', err)
      )
  }

<input name='avatar' onChange={fileselectedHandler} type={'file'}/> <button onClick={fileuploadHandler}>Upload Picture</button>

Problem is whenever I hit Upload picture button request is being sent but the response is like this data: {msg: "Error:No file selected"} and in the body which is sending is this data: "{"avatar":{}}". Any suggestions why is this happening and how to fix it ?

Nika Roffy
  • 891
  • 2
  • 8
  • 20

1 Answers1

1

It seems you are not making a multipart request form the front-end (Content-Type header should be multipart/form-data, see first note on npm page of multer)

In this answer, take a look at the fileUpload function in the code which makes use of the FormData web API (WARNING: may run into compatibility issues with Internet Explorer).

See if this helps.

Anuj Pancholi
  • 1,153
  • 8
  • 13