How to send a file/image from React to node.js server
11,185
Finally, I found out how to solve that problem.
onSubmit = e => {
e.preventDefault();
const { user } = this.props.auth;
const form = new FormData();
form.append("file", this.state.file);
form.append("theme", this.state.theme);
form.append("text", this.state.text);
form.append("name", user.username);
form.append("avatar", user.avatar);
this.props.createPost(form);
}
Author by
Ilya Solodeev
Updated on June 06, 2022Comments
-
Ilya Solodeev almost 2 years
I'm trying to send a file/image from React to node.js server with multer. The problem is I can send an image only through Postman but when I'm trying the same in React I'm getting: TypeError: Cannot read property 'path' of undefined. I don't understand whether I should send a file/image in binary or use another format. I've already tried to use reader.readAsDataURL() and reader.readAsBinaryString() but it didn't work.
const multer = require("multer"); const storage = multer.diskStorage({ destination: (req, file, cb) => { cb(null, "./uploads/"); }, filename: (req, file, cb) => { cb(null, new Date().toISOString() + file.originalname); } }); const fileFilter = (req, file, cb) => { if ( file.mimetype === "image/jpeg" || file.mimetype === "image/png" || file.mimetype === "image/jpg" ) { cb(null, true); } cb(null, false); }; const upload = multer({ storage: storage, limits: { fileSize: 5000000 }, fileFilter: fileFilter }); // Create a post router.post( "/", upload.single("image"), passport.authenticate("jwt", { session: false }), (req, res) => { const { errors, isValid } = validationPostInput(req.body); if (!isValid) { return res.status(400).json(errors); } console.log(req.file); const newPost = new Post({ text: req.body.text, theme: req.body.theme, name: req.body.name, avatar: req.body.avatar, image: req.file.path, user: req.user.id }); newPost.save().then(post => res.json(post)); } );
// CREATE A POST export const createPost = (userInput, history) => dispatch => { const headers = { "Content-Type": "form-data" }; axios .post("/post", userInput, headers) .then(res => history.push("/post/all")) .catch(err => dispatch({ type: GET_ERRORS, payload: err.response.data }) ); };
import React, { Component } from "react"; import PropTypes from "prop-types"; // import { Link } from "react-router-dom"; import { connect } from "react-redux"; import { createPost } from "../../actions/postActions"; import "./style.css"; class CreatePost extends Component { state = { text: "", theme: "", image: "", errors: {} }; componentWillReceiveProps(nextProps) { if (nextProps.errors) { this.setState({ errors: nextProps.errors }); } } onSubmit = e => { e.preventDefault(); const { user } = this.props.auth; const newPost = { text: this.state.text, theme: this.state.theme, image: this.state.image, name: user.username, avatar: user.avatar }; this.props.createPost(newPost); }; onChange = e => this.setState({ [e.target.name]: e.target.value }); fileSelectHandler = e => { const param = e.target.files[0]; let reader = new FileReader(); reader.readAsDataURL(param); this.setState({ image: reader.result }); console.log(reader); }; render() { const { text, theme, errors } = this.state; return ( <section className="post"> <form onSubmit={this.onSubmit} className="post__form" action="/post" method="POST" encType="multipart/form-data" > <div className="post__form--input"> <label>Theme</label> <input type="text" name="theme" value={theme} onChange={this.onChange} /> {errors && <small>{errors.theme}</small>} </div> <div className="post__form--input"> <label>Text</label> <textarea type="text" name="text" value={text} onChange={this.onChange} /> {errors && <small>{errors.text}</small>} </div> <div className="post__form--file"> <label>Add Image</label> <input type="file" name="file" accept=".png, .jpg" onChange={this.fileSelectHandler} /> </div> <button type="submit" className="button"> Submit </button> </form> </section> ); } } CreatePost.propTypes = { errors: PropTypes.object.isRequired }; const mapStateToProps = state => ({ errors: state.errors, auth: state.auth }); export default connect( mapStateToProps, { createPost } )(CreatePost);
-
Admin almost 5 yearshey can you generate a prototype here, it will be easy for debugging codesandbox.io/s/node
-
Ilya Solodeev almost 5 yearsmy server connects to mongoDB, I don't think I can do it
-
Admin almost 5 yearsmaybe you can mock your data
-
-
Ilya Solodeev almost 5 yearsI changed but I got the same issue. Perhaps the problem in data I'm trying to send. Which format multer can red?