question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

req.file and req.files are undefined - using React and Node

See original GitHub issue

I have read and re-read similar posts and cannot figure out what is wrong with my code. No matter what I do, the file is not being read in the back. Console logging the value in the front shows the correct file, but it is always undefined or an empty object in the back and isn’t saving in the correct folder.

// -------------------  './server.js'

require('dotenv').config();
const express = require('express');
const path = require('path');
const cloudinary = require('cloudinary').v2;
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/fcf_backend', { useNewUrlParser: true, useCreateIndex: true }); // for local dev
// mongoose.connect(process.env.MONGODB_URI, {useMongoClient: true});  // for heroku deployment

const app = express();

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cookieParser());

cloudinary.config({
  cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
  api_key: process.env.CLOUDINARY_API_KEY,
  api_secret: process.env.CLOUDINARY_API_SECRET,
});

const announcements = require('./routes/announcements');
const auth = require('./routes/auth');
const manager = require('./routes/manager');

app.use('/announcements', announcements);
app.use('/auth', auth);
app.use('/manager', manager);

if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, 'client/build')));

  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, 'client/build', 'index.html'));
  })
}

// npm run dev to run in dev mode
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => console.log(`App listening on port ${PORT}!`));

module.exports = app;
// --------------------  './routes/announcements.js'

const express = require('express');
const router = express.Router();

const cloudinary = require('cloudinary').v2;
const mongoose = require('mongoose');
const multer = require('multer');

// have tried both methods below and neither works
const upload = multer({ dest: './uploads' });

// this doesn't work either
// const storage = multer.diskStorage({
//   destination: (req, file, cb) => {
//     cb(null, './uploads')
//   },
//   filename: (req, file, cb) => {
//     cb(null, `${Date.now()}-${file.originalname}`);
//   },
// });
// const upload = multer({ storage });

const Announcement = require('../models/announcement');

router.post('/', upload.single('imgFile'), (req, res) => {
  const { announcementText, file, url } = req.body;
  console.log(file); //  --> {}
  console.log(req.file);  //  --> undefined
  res.send('success');
});

module.exports = router;
// --------------  React form in client

import React from 'react';
import axios from 'axios';

export default class AddAnnouncement extends React.Component {
  constructor(props) {
    super(props);
    this.url = React.createRef();
    this.state = {
      allowTypingPastLimit: false,
      announcementText: '',
      charCount: 0,
      charLimit: 150,
      imgFile: '',
      imgUrl: '',
    }
  }

  handleImgChange = e => {
    const imgFile = e.target.files[0]
    this.setState({ imgFile });
  }

  handleSubmit = e => {
    e.preventDefault();
    const { announcementText, imgFile } = this.state;
    let file = new FormData();
    file.append('imgFile', imgFile);
    for (let value of file.values()) {
      console.log('value: ', value)  //  --> shows file info
    }
    axios.post('/announcements', {
      announcementText,
      file,
      url: this.url.current.value
    }).then(result => {
        console.log(result)  // --> success
    });
  }

  render() {
    const { allowTypingPastLimit, announcementText, charLimit, imgUrl } = this.state;
    const disabled = this.isTextLTEtoLimit()(announcementText.length) ? '' : 'disabled';
    return (
        <form encType="multipart/form-data" className='AddAnnouncement__form' onSubmit={this.handleSubmit}>
            <div className='AddAnnouncement__form__img-wrap'>
              <label htmlFor='new-announcement-img'>Image</label>
              <input
                id='new-announcement-img'
                name='imgFile'
                onChange={this.handleImgChange}
                ref={this.img}
                type='file'
              />
            </div>
          <button className={disabled} disabled={disabled} type='submit'>Add Announcement</button>
        </form>
    );
  }
}

I deleted superfluous code here, so there may be a few bits that look random that I missed deleting. If anyone can help point out what’s wrong, that would be super helpful. Thank you.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

4reactions
LinusUcommented, Jan 11, 2019

You cannot but a File object in the middle of Axios post data, you need to put everything that you want to send inside the FormData object and use that as the body.

Here is some more info: https://stackoverflow.com/a/47630754/148072

Good luck!

0reactions
tanmay-kalicommented, Dec 14, 2022

Facing the same issue lol

Read more comments on GitHub >

github_iconTop Results From Across the Web

req.file is undefined (react.js and multer)
When I am doing a console.log(req.file), I got an "undefined" I don't know what I'm missing I am using node.js, mySql (sequelize). React...
Read more >
Node.js - req.files returns "undefined" when sending POST ...
I am having some difficulty getting a file to upload to a node.js ... Node.js - req.files returns "undefined" when sending POST to...
Read more >
Express multer middleware
Multer is a node.js middleware for handling multipart/form-data , which is primarily used for uploading files. It is written on top of busboy...
Read more >
File uploads using Node.js
To answer your question, you can get the uploaded file by storing the path variable present in req.files and return it to client...
Read more >
#8 FILE UPLOADING IN NEXT.JS USING MULTER ... - YouTube
JS USING MULTER#GET RID OF req. file , req.body UNDEFINED #NEXT-CONNECT ... IN MYSQL DB):https://youtu.be/E5QOIeIwgo8 JAVE+ NODE + REACT PART ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found