3

I am trying to upload a single file, and store it in a folder in my app directory. On the frontend, I am successfully selecting a file and adding it to the state of the Uploader component. When I make the POST request to the Node route with Axios, I am getting undefined in the request body.

Here is the component:

import React, { Component } from 'react';

import axios from 'axios';

export default class SandboxGet extends Component {
  constructor(props) {
    super(props);
    this.state = {
      file: null
    };
  }

  fileSelectHandler = event => {
    const file = event.target.files[0];
    this.setState({ file: file.name });
  };

  fileUploadHandler = () => {
    const data = new FormData();
    data.append('file', this.state.file);
    console.log(data);
    axios
      .post('http://localhost:4000/upload/', this.state.file, {
        // receive two    parameter endpoint url ,form data
      })
      .then(res => {
        // then print response status
        console.log(res.statusText);
      });
  };

  render() {
    return (
      <div className="uploaderContainer">
        <div className="uploadInput">
          <i className="fas fa-upload" />
          <button className="uploadBtn">Select Files</button>
          <input type="file" name="file" onChange={this.fileSelectHandler} />
          <div className="fileName">{this.state.fileName}</div>
        </div>
        <button className="uploadFile" onClick={this.fileUploadHandler}>
          Upload!
        </button>
      </div>
    );
  }
}

Here is the Node server:

const express = require('express');
const app = express();
const multer = require('multer');
const cors = require('cors');

app.use(cors());

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

const upload = multer({ storage: storage }).single('file');

app.post('/upload', (req, res) => {
  console.log(req.file); // => returns nothing
  console.log(req.body; // => returns nothing
  upload(req, res, function(err) {
    if (err instanceof multer.MulterError) {
      return res.status(500).json(err);
    } else if (err) {
      return res.status(500).json(err);
    }
    return res.status(200).send(req.file);
  });
});

app.listen(4000, function() {
  console.log('App running on port 3000');
});

I feel like I am getting close, but I am missing a big piece of the puzzle.

maison.m
  • 813
  • 2
  • 19
  • 34
  • Tip: Before working with axios and sending requests to your backend, first see if your backend actually works. You can send test requests with Postman and make sure your backend works. Then, you can move on to axios. – Fatih Aktaş Jun 18 '19 at 19:54
  • I think you should pass the entire file object, not just the filename. have a look at https://stackoverflow.com/questions/41878838/how-do-i-set-multipart-in-axios-with-react – miedwar Jun 18 '19 at 19:55

1 Answers1

1

You are sending the this.state.file. You need to send the FormData.

In your case it is .post('http://localhost:4000/upload/', data) Also, you need to send the multipart/form-data header.

const headers = {
    'content-type': 'multipart/form-data'
}

Then,

axios.post('http://localhost:4000/upload/', data, {headers});
Aritra Chakraborty
  • 12,123
  • 3
  • 26
  • 35