req.file and req.files are undefined - using React and Node
See original GitHub issueI 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:
- Created 5 years ago
- Comments:7 (1 by maintainers)
Top 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 >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
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!
Facing the same issue lol