Search code examples
node.jsreactjsaxiosmultipartform-data

FormData is empty at the backened


I'm using axios to post a form(includes file) using FormData to the backened in react but the request data is empty at backened.

Note : formData is not empty in payload of Chrome browser.
App.js

const App = ({data, id}) => {
  const [temperoryLink, setTemperorylink] = useState('');
 const [assignment, setAssignment] = useState('');

 const handleFileUpload = (e) => {
   const linkObject = e.target.files[0];
   const temperoryLink = URL.createObjectURL(linkObject);
   setTemperorylink(temperoryLink);
   setAssignment(linkObject);
 };

const handleSubmit = async (e) => {
   e.preventDefault();
   try {
     const formData = new FormData();
     formData.append('file', assignment);
     formData.append('ta_id', data.assigned_TA);
     formData.append('assignmentId', id);

       const response = await SubmitAssignmentApi(formData);
      
   } catch (err) {
     console.log(err);
   }
 }

return (
 <div>
  <label className="btn">
    <input
      type="file"
      name="file"
      style={{ display: 'none' }}
      onChange={handleFileUpload}
      required
     />{' '}
     Upload file
   </label>
   <button type="submit" className="btn bg-red-five" onClick={handleSubmit}>
      Submit
   </button>
</div>
)
}

submit.js

export async function SubmitAssignmentApi(formData) {
  try {

    const config = {
      headers: {
        'Content-Type': 'multipart/form-data',
        Authorization: `Bearer ${token}`
      }
    };
    const response = await axios.post('http://localhost:5000/api/v1/submission/', formData, config);
    return response.data;
  } catch (err) {
    console.log(err);
  }
}

Below code is a backened code where request is send from client to server backened.js

const SubmitAssignment = require('../../../../controller/api/v1/assignment/submission');
router.post('/', [
  body('assignmentId').not().isEmpty().withMessage('Assignment ID is required'),
  body('ta_id').not().isEmpty().withMessage('Teaching Assistant Id is required'),
], authenticateUserToken, SubmitAssignment.submit);


const upload = multer({ dest: 'uploads/' });

exports.submit = async(req, res) => {
  try {
    // validate client input data
    upload.single('file');
    console.log(req.body);
    console.log(req.file);

    const error = validationResult(req);
    if (!error.isEmpty()) {
      return res.status(422).json({
        type: 'warining',
        message: error.array()[0].msg,
      });
    }

   } catch (err) {
    console.log(err);
    return res.status(500).json({
      success: false,
      message: 'Server Error',
    });
  }
};

any suggestions would be appreciated.


Solution

  • upload.single('file') returns a middleware function. Therefore, you should either add it to the list of middlewares of the router.post function call, or invoke it properly as follows (which is very less common);

    const theRealUpload = upload.single('file');
    theRealUpload (req, res, function (err) {
        if (err) {
          // Handle error
        }
    
        // Do your stuff here...
    })