6

I need to upload a file in React and then send it to an Express server (I'm new to Express so it's hard for me),

I succeed to upload the file in my React Component, but now I don't know how to send it to my back-end server made with Express.

What do I need to use ? Axios or Fetch ? Get or Post ? Thank you !

my App.js file (front-end)

    uploadFile = () => {
    const { currentFileName, currentFileType } = this.state;
    if (currentFileName && currentFileType) {
      fetch('http://localhost:5000/upload/files', {
        method: "POST",
        headers: {
          'Content-type': 'application/json'
        },
        body: JSON.stringify(this.state)
      })
      .then((res) => res.json())
      .then(res => {
        this.setState({
          errorMessage: "",
          successMessage: `Votre fichier ${currentFileName} a bien été uploadé !`
        });
        console.log(res);
        console.log(res.data);
      })
    } else {
      this.setState({
        errorMessage: "Veuillez choisir un fichier avant d'appuyer sur le bouton Upload !"
      });
    }
  }

and my server.js file (back-end)

const express = require('express');

const app = express();

const router = express.Router();

app.use(function(req, res, next) {
    res.header('Access-Control-Allow-Origin', 'http://localhost:3000');
    res.header('Access-Control-Allow-Credentials', true);
    res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
res.header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE');
next();
});

const bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));

app.post('/upload/files', (req, res) => {
    var fileName = req.body.currentFileName;
    var fileType = req.body.currentFileType;
console.log('Nom du fichier: ' + fileName + ' ' + 'Type du fichier: ' + fileType);
res.send(fileName + fileType);
});

const port = 5000;

app.listen(port, () => `Server running on port ${port}`);

I expect to get the state datas in localhost:5000/upload/files but when I go on the URL I have the message "Cannot GET /upload/files"

Can someone help me please ? Thank you !

4 Answers 4

5

You can use axios to upload the file.

const yourFile = file // Assume this is your file.

Now you need to add it to a form data.

const formData = new FormData();
formData.append('file', yourFile);

now:

axios.post('/yourEndpoint', formData).then(res => {
  //Now do what you want with the response;
})

In your NodeJS app:

app.post('/yourEndpoint', function(req,res){
  fs.readFile(req.files.file.path, function(err, data){
    // Do something with the data (which holds the file information)
  });
});
Sign up to request clarification or add additional context in comments.

2 Comments

no need to configure header ( "Contetnt-Type":"multipart/form-data" ) with axios ? or is this necessary
is there any way without using FormData
5

In your frontend, grab your file:

 <input type="file" id="inputGroupFile01" 
    onChange={(e) => this.onSelectImageHandler(e.target.files)}
/>

You must send the file to the server as form data as follows:

onSelectImageHandler = (files) => {
    const file = files[0];
    const formData = new FormData();
    formData.append('file', file)

    const config = {
        headers: {
            "Content-Type":"multipart/form-data" 
        }
    };
}

Once you have your form data setup, you can make the call with axios or fetch.

Then you need to install multer package on your server side:
npm i -S multer, then on your server.js file:

const multer = require('multer');

You can configure multer just at the beginning after all requires.

const upload = multer({dest: 'public/uploads/'}).single('file');

Then in your route:

app.post('/upload/files', (req, res) => {
    upload(req,res, (err) => {
        const file = req.file
    const prevUrl = req.body.prevUrl.slice(21) //I use slice to cut the public part of the path, since mine is accessible from anywhere.
    if(!err){
        //here you could add some call to save the prevUrl "url of the file to called it later on your front"
        return User.findOneAndUpdate({_id:req.decoded.userId},{avatarUrl:avatarUrl}, (err, user) => {
            if(!err){       
                return console.log(err)
                })
                return res.json({success:true, message:"File has been successfully uploaded",avatarUrl:"http://localhost:3231/uploads/"+file.filename});
            }
            console.log(err);
        })
    }
    console.log(err);
    })
});

Hope it helps.

Comments

0

Since you're trying to send a file, it's better to use a Post (quick tip : Get is used when you need to get data from server and Post is used when you need to post data to the server).

Then for express, you should look at multer wich is a middleware for handling multipart/form-data.

Finally, in your react, you juste need to send the file in a mutlipart form with fetch

1 Comment

ok I used post, but now I don't know how to display the datas I sent from my React component to the back-end endpoint. I will watch about multer, thank you
-1

It is because you are using app.post.

The app.post function listens for post requests(not get).

to also make it run for get request you have to use the app.get function

ie:-

app.get("/upload/files",(req,res)=>{res./*status(400).*/send("please use a post request")})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.