store images in postgresql from react using express multer - node.js

I'm trying to save images from my react app to backend using nodejs(express) and multer, I tried from these How to upload image using javascript fetch api and express multer
after I got the message file uploaded, how do you store it to database?
Here's the code in my react app
class UploadCover extends React.Component {
constructor(props){
super(props);
this.state={
id: this.props.location.state.id,
selectedFile : '',
imagePreviewUrl: ''
}
}
//handle image change
handleImageChange = (e) => {
e.preventDefault();
let reader = new FileReader();
let file = e.target.files[0];
reader.onloadend = () =>{
this.setState({
selectedFile:file,
imagePreviewUrl: reader.result
});
};
reader.readAsDataURL(file);
this.handleUploadCover(e.target.files[0]);
}
//upload cover
handleUploadCover = (file) => {
let form = new FormData(this.refs.myForm);
form.append('myImage', file);
fetch('http://localhost:3001/upload-cover', {
method: 'post',
header: { "Content-Type" : "application/json"},
body: form
})
.then( res =>res.json())
.then(data => console.log("data: ", data))
};
render() {
const { classes, ...rest } = this.props;
const { id, imagePreviewUrl } = this.state;
console.log("url: ", imagePreviewUrl)
let $imagePreview = null;
if(imagePreviewUrl){
$imagePreview = <img style={{width: "100%", height: "100%"}} src={imagePreviewUrl}/>;
}else{
$imagePreview = (
<div className={classes.previewText}>Please select cover</div>
);
}
return (
<div>
<HeaderHome/>
<div className={classNames(classes.main, classes.mainRaised)}>
<div className={classes.container}>
<div className={classes.storymargin}>
<h2 className={classes.title}>Upload Cover Story</h2>
<Card className={classes.uploadcontainer}>
<CardContent>
<div className={classes.imgPreview}>{$imagePreview}</div>
<form ref='myForm' encType='multipart/form-data'>
<input
accept="image/*"
className={classes.input}
id="raised-button-file"
multiple
type="file"
onChange={ e => this.handleImageChange(e)}
// ref='myForm'
/>
</form>
<label htmlFor="raised-button-file">
<Button component="span" className={classes.buttonupload}>
Choose Image
</Button>
</label>
</CardContent>
<CardActions>
<Link
to={{
pathname: "/create-chapter",
state: {id : id}
}}
>
<Button size="small" clor="primary" className={classes.buttonnextup}
onClick={ e => this.handleUploadCover(e) }
>
Next
</Button>
</Link>
</CardActions>
</Card>
</div>
</div>
</div>
<div className={classes.footer}>
<Footer />
</div>
</div>
);
}
}
and here's the backend
//set storage engine
const storage = multer.diskStorage({
destination: './public/uploads',
filename: (req, file, cb) => {
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
})
//Init upload
const upload = multer({
storage: storage,
limits: {fileSize: 1000000},
fileFilter: (req, file, cb) => {
checkFileType(file, cb);
}
}).single('myImage');
//Check File Type
checkFileType = (file, cb) => {
//Allowed ext
const filetypes = /jpeg|jpg|png|gif/;
//Check ext
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
//Check mime
const mimetype = filetypes.test(file.mimetype);
if(mimetype && extname){
return cb(null, true);
}else{
cb('Error: Images Only');
}
}
//upload cover story
app.post('/upload-cover', (req, res) => {
console.log('handling upload image');
upload( req, res, (err) => {
if(err){
console.log('first err', err);
res.send({
msg: err
});
}else{
if(req.file === undefined){
console.log('Error: No File Selected');
res.send({
msg: 'Error: No File Selected'
});
}else{
console.log('File Uploaded');
res.send({
msg: 'File Uploaded',
file: `uploads/${req.file.filename}`
});
}
}
});
});
and how can i send request with content type application/json and multipart/form-data at the same time through body request, I want to send form and id:this.state.id

Related

Multer not able to get the filename

I'm not able to get the filename or path from Multer. This is what I've done so far:
uploadcsv.js
const fileUpload = multer({
limits: 500000,
storage:multer.diskStorage({
destination: (req, file, cb) =>{
cb(null,'upload/csv')
},
filename: (req, file, cb) =>{
const ext = MIME_TYPE_MAP[file.mimetype]
cb(null, uuid + '.' + ext)
},
fileFilter: (req, file, cb) =>{
const isValid = !!MIME_TYPE_MAP[file.mimetype]
let error = isValid ? null : new Error('Invalid mime type')
cb(error, isValid)
}
})
})
Then the route api:
router.post('/contact/importcontact', JWTAuthenticationToken, fileUpload.single('csv'), async (req, res) => {
console.log(req.body)
console.log(req.file.filename)
const csvFilePath = req.file.filename
const stream = fs.createReadStream(csvfile);
const account= await Account.findOne({ acctid: { "$eq": req.body.acctid } })
try {
if (req.file == undefined)
return res.status(400).send({ msg: 'No files were uploaded.' });
csvtojson()
.fromFile(csvFilePath)
.then((jsonObj) => {
console.log(jsonObj);
})
// Async / await usage
const jsonArray = await csvtojson().fromFile(csvFilePath);
res.json({ success: "Uploaded Successfully", status: 200 })
} catch (error) {
res.json({ message: error })
}
})
Lastly, the react importcustomer.js
const handleCSVChange = (e) => {
console.log(e.target.files[0])
setCsvData(e.target.files[0])
setUploadButtonData(e.target.files[0].name)
}
const uploadCSVData = async (e) => {
setLoading(true)
const formData = new FormData();
formData.append("csv", csvData);
console.log(formData)
e.preventDefault()
const response = await Axios.post(process.env.REACT_APP_FETCH_URL + '/api/contact/importcontact', { formData: formData, acctid: lsData.acctid}, { withCredentials: true })
if (response.data.statusCode === "409") {
setMessage(response.data.msg)
setLoading(false)
}
else if (response.data.statusCode === "200") {
setLoading(false)
//history.push('/sources')
}
}
return (
<div className="col-12 grid-margin stretch-card">
<div className="card">
<div className="card-body">
<h4 className="card-title">Import Customer Data From CSV</h4>
<form className="forms-sample" enctype="multipart/form-data">
<div className="form-group">
<label for="files" className="btn btn-primary">{uploadButtonData}
<input id="files" type="file" name="csv" className="form-control" hidden accept="*.csv" onChange={handleCSVChange} /></label>
</div>
<button className="btn btn-primary" onClick={uploadCSVData} style={{ float: "right", width: "7rem" }} type="button">
{loading && <i className="fa fa-refresh fa-spin"></i>}
Upload CSV</button>
<div className="mt-3" style={{ textAlign: "center" }}>
<span id="msg" style={{ color: "red" }}>{message}</span>
</div>
</form>
</div>
</div>
</div>
)
Though I'm able to console.log(req.body) and console.log(e.target.files[0]) and getting the acctid and filename but returned empty for the console.log(formData) and console.log(req.file.filename) returned undefined. What have I missed? Many thanks in advance and greatly appreciate any helps. Thanks again
I have managed to solves this by appending the acctid to formData:
const formData = new FormData();
formData.append("csv", csvData);
formData.append("accctid", lsData.acctid);
const response = await Axios.post(process.env.REACT_APP_FETCH_URL + '/api/contact/importcontact', formData, { withCredentials: true })

Trying to send formData with another parameter via axios

I have a form that uploads single files via a FormData object. In addition to the file attribute, I want to also assign this file to a Group.
I can't figure out how to add the group object id to the request.
Here is my upload component:
<template>
<div>
<div class="ui attached segment rounded mb-3">
<form #submit.prevent="sendFile" enctype="multipart/form-data" class="ui form">
<div v-if="message" class="`message ${error ? 'text-danger' : 'text-success'}`">
<div class="message-body"> {{ message }}</div>
</div>
<div class="field">
<label for="file" class="label">Upload File</label>
<input
type="file"
ref="file"
#change="selectFile"
class="file-input"
/>
<!-- <span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="file-label">
Choose a file...
</span>
</span> -->
<span v-if="file" class="file-name">{{file.name}}</span>
<div class="field">
<button class="btn btn-info">Send</button>
</div>
</div>
</form>
</div>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: "SimpleUpload",
data() {
return {
file: "",
message: '',
error: false
}
},
computed: {
currentGroup() {
return this.$store.getters.currentGroup;
}
},
methods: {
selectFile() {
const file = this.$refs.file.files[0];
const allowedTypes = ["image/jpeg", "image/png", "image/gif"];
const MAX_SIZE = 200000;
const tooLarge = file.size > MAX_SIZE;
if (allowedTypes.includes(file.type) && !tooLarge) {
this.file = file;
this.error = false;
this.message = '';
} else {
this.error = true;
this.message = tooLarge ? `Too large. Max size is ${MAX_SIZE/1000}kb` : "Only images are allowed"
}
},
async sendFile() {
const formData = new FormData();
formData.append('file', this.file);
formData.append('group', this.currentGroup);
console.log('file is: ', this.file)
console.log('this is form data after file is added: ', formData)
try {
await axios.post('/uploads', {
formData,
group_id: this.currentGroup.id
});
console.log('this is the formData being sent: ', formData)
this.message = 'File has been uploaded';
this.file = '';
this.error = false;
} catch(err) {
this.message = err.response.data.error;
this.error = true
}
}
}
}
</script>
Here is my route in :
const Group = require('../models/Group');
const Upload = require('../models/Upload');
const router = express.Router();
const upload = require('../services/file-uploads');
const singleUpload = upload.single('file'); // has to match front end
router.post('/', auth.required, async function(req, res) {
console.log ('upload route is hit')
let results = await singleUpload(req, res, async function (err) {
if (err) {
return res.status(422).send({ errors: [{title: 'File upload error, detail: err.message'}] });
} else {
console.log('this is the upload reqest fobject: ', req);
console.log("trying to save data to postgres");
// console.log('this is the originalname of the reqest file object: ', req.file);
console.log('this is the upload reqest body: ', req.body.group_id);
await Upload.query()
.insert({
name: req.body.file.originalname,
users_id: req.user.id,
filetype: req.body.file.mimetype,
filesize: req.body.file.size,
file_url: req.body.file.location,
groups_id: req.body.group_id
})
res.json({
success: true,
message: 'ok'
});
res.json(results)
}
})
});
module.exports = router;
and the upload config in services/file-uploads:
const aws = require('aws-sdk');
const multer = require('multer');
const multerS3 = require('multer-s3');
aws.config.update({
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
region: 'us-east-1'
})
const s3 = new aws.S3();
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true)
} else {
cb(new Error('Invalid Mime Type, only JPEG and PNG'), false);
}
}
const upload = multer({
storage: multerS3({
s3: s3,
bucket: process.env.AWS_BUCKET,
acl: 'public-read',
metadata: function (req, file, cb) {
cb(null, {fieldName: 'TESTING_META_DATA!'});
},
key: function (req, file, cb) {
cb(null, Date.now().toString())
}
})
})
module.exports = upload;
In the request, I see body: { formData: {}, group_id: 1 },
and I can retrieve the group_id with req.body.id, but the formData object is empty
Prepare the FormData like this:
const formData = new FormData();
formData.append('file', this.file); // Append a file
formData.append('group_id', this.currentGroup.id); // Append a field
And then send it like this:
await axios({
method: 'post',
url: '/uploads',
data: formData,
headers: {
'Content-Type': 'multipart/form-data'
}
});

Avatar is saved to MongoDB but no success message and rendering of avatar in component, using React and Multer

Depending on your viewpoint, I was able to get the most important part of getting a Avatar/Image in an app...pushing to the database (MongoDB in my case, Also the image gets added to my server folder).
However what I can't get working is the success modal to fire or the rendering of the image on the page, which is strange as the response.status === 200 and response.ok === true? I am using Multer in Express. (I am using fetch).
This is my ImageLoader component:
import React, { Component } from 'react';
import './ImageUploader.css';
import Modal from '../Modal/MyModal.jsx'
import DefaultImg from '../../static/profile-avatars/assets/default-img.jpg';
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { modalStateOn, modalStateOff } from '../../store/index'
const API_URL = "http://localhost:8016";
class ImageUploader extends Component {
constructor(props) {
super(props);
this.state = {
multerImage: DefaultImg,
}
}
setDefaultImage(uploadType) {
if (uploadType === "multer") {
this.setState({
multerImage: DefaultImg
});
}
}
uploadImage(e, method) {
var { history, isLoggedIn, modalActive, modalStateOn, modalStateOff } = this.props
let imageObj = {};
if (method === "multer") {
let imageFormObj = new FormData();
imageFormObj.append("imageName", "multer-image-" + Date.now());
imageFormObj.append("imageData", e.target.files[0]);
// stores a readable instance of
// the image being uploaded using multer
this.setState({
multerImage: window.URL.createObjectURL(e.target.files[0])
});
return window.fetch('http://localhost:8016/images/uploadmulter', {
method: 'POST',
// body: e.target.files[0]
body: imageFormObj
})
.then((response) => {
console.log("response ", response);
this.setDefaultImage("multer");
return (
<>
{response.ok && <Modal
isAlertModal={true}
history={history}
affirmativeUsed="Yes"
message="Image has been successfully uploaded!"
isLoggedIn={isLoggedIn}
modalActive={true}
modalStateOn={modalStateOn}
modalStateOff={modalStateOff}></Modal>}
</>
)
})
.then((data) => {
console.log("data ", data);
this.setDefaultImage("multer");
})
.catch(error => {
this.setDefaultImage("multer");
console.log("error ", error);
})
}
} // end upload function
render() {
// console.log("uploadImage function this.props ", this.props);
return (
<div className="main-container">
<h3 className="main-heading">Image Upload App</h3>
<div className="image-container">
<div className="process">
<h4 className="process__heading">Process: Using Multer</h4>
<p className="process__details">Upload image to a node server, connected to a MongoDB database, with the help of multer</p>
<form action="/uploadmulter" method="post" encType="multipart/form-data" >
<input type="file" name="avatar" className="process__upload-btn" onChange={(e) => this.uploadImage(e, "multer")} />
<img src={this.state.multerImage} alt="upload-image" className="process__image" />
</form>
</div>
</div>
</div>
);
}
}
function mapStateToProps(state) {
const { isLoggedIn, modalActive } = state
return { isLoggedIn, modalActive }
}
const mapDispatchToProps = dispatch =>
bindActionCreators({ modalStateOn, modalStateOff }, dispatch)
export default connect(mapStateToProps, mapDispatchToProps)(ImageUploader)
And this is the route on my express server server/images/index.js:
var router = require('express').Router();
var Image = require('../models/Image');
var multer = require('multer')
var storage = multer.diskStorage({
destination: function(req, file, cb){
cb(null, './server/uploads/');
},
filename: function(req, file, cb){
cb(null, Date.now() + file.originalname)
}
})
var fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
// rejects storing a file
cb(null, false)
}
}
var upload = multer({
storage: storage,
limits : {
fileSize : 1024 * 1024 * 5
},
fileFilter: fileFilter
})
router.route('/uploadmulter')
.post(upload.single('imageData'), (req, res, next) => {
console.log('req.body', req.body);
var newImage = new Image({
imageName: req.body.imageName,
imageData : req.file.path
})
newImage.save()
.then(result => {
res.status(200).json({
success: true,
document:result
})
})
.catch(err=> next(err))
});
module.exports = router
So to reiterate why doesn't the image render and modal fire when the response is true or 200?

file upload in react and node js not working

i am trying very hard to upload file but no way i could find a clear solution .
i have tried many ways but not working . Now the console shows me 200 and give me message that file is uploaded but file is not going in the folder . i ahve checked file size limit and folder is ok but dont know why its not working. could any help please.
///react component
import { saveBasicUser, getOneBasicUser, uploadFile } from
'../../actions/basicAction';
this.state = { file: []};
handleChange(event) {
this.setState({
[event.target.name]: event.target.value,
file:
event.target.files})
}
handleSubmit(event) {
event.preventDefault();
var file = this.state.file
let formData = new FormData();
formData.append('file', file);
// console.log(obj);
console.log(formData);
// this.props.dispatch(saveBasicUser(obj ))
this.props.dispatch(uploadFile(formData ))
}
<form onSubmit={this.handleSubmit} encType="multipart/form-data">
<input type="file" name = "file" onChange={this.handleChange} />
<button type="submit" className="btn btn-success btn-lg">Submit</button>
////////action part
export function uploadFile(formData) {
console.log(formData)
return (dispatch) => {
return axios.post('/upload_file', {
headers: { 'content-type': 'multipart/form-data' },
data: formData
}).then(function (res) {
console.log(res)
}).catch(function (err) {
console.log(" err")
console.log(err)
})
}
}
//////server part
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now()+ path.extname(file.originalname))
}
})
var upload = multer({ storage: storage, limits: {fileSize : 1000000} }).single('file');
app.post('/upload_file', function(req, res){
upload(req, res, function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
I have found the solution at last.
react JS
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import Messages from '../Messages';
import classnames from 'classnames';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';
import { getOneBasicUser ,uploadFile} from '../../actions/basicAction';
//--------------------------------------------------------------------------
class Upload extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
this.handleChange = this.handleChange.bind(this);
this.handleFile = this.handleFile.bind(this);
}
//--------------------------------------------------------------------
//--------------------------------------------------------------------------
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
//--------------------------------------------------------------------------
handleFile(e) {
e.preventDefault();
var id = this.props.params.id;
console.log(id);
var formData = new FormData($('form')[0]);
var isFileExist = !!$('input[type=file]')[0].files[0];
if (isFileExist) {
$.ajax({
url: '/upload_file/'+ id,
type: 'POST',
data: formData,
xhr: function () {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener("progress", function (e) {
if (e.lengthComputable) {
$('progress').attr({value: e.loaded, max: e.total});
$('#status').empty().text(parseInt((e.loaded / e.total * 100)) + '%');
}
}, false);
return xhr;
}.bind(this),
success: function (data) {
this.setState({
data: data
});
$('#status').empty().text('File Uploaded!');
}.bind(this),
error: function (xhr, status, err) {
console.log( err);
}.bind(this),
cache: false,
contentType: false,
processData: false
});
} else {
$('#status').empty().text('Please choose the file.');
}
}
//--------------------------------------------------------------------------
render() {
return (
<div className="container ca-container">
<div className="row">
<div className="col-md-12">
<h2> Upload File </h2>
<hr />
</div>
</div>
<form onSubmit={this.handleFile} encType="multipart/form-data">
<div className="row">
<div className="col-md-12">
<div className="col-md-6">
<h3 id="status" className ="label label-success"></h3>
<div className="form-group">
<label>
Name:
</label>
<input type="file" className="form-control" name="BasicUserFile" onChange={this.handleChange} placeholder="file" />
</div>
<div className="btn-group" role="group">
<button type="submit" value="Upload File" className="btn btn-success btn-lg">Upload</button>
</div>
</div>
</div>
</div>
</form>
</div>
);
}
}
// ======================== REDUX CONNECTORS ========================
const mapStateToProps = (state) => {
return {
//basicUser: state.basicUser.basicUser
};
};
export default connect(mapStateToProps)(Upload);
////server.js
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './uploads')
},
filename: function (req, file, cb) {
var basic_id = req.params.id
cb(null, file.fieldname + '-' + basic_id+ path.extname(file.originalname))
}
})
var upload = multer({ storage: storage, limits: {fileSize : 1000000} }).single('BasicUserFile');
app.post('/upload_file/:id', function(req, res){
console.log("000000000000000000000000000000000000000000000000")
console.log(req.params)
console.log("000000000000000000000000000000000000000000000000")
upload(req, res, function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});

file not uploading in react js and nodejs using multer

console.log giving this but file is not uploading
{
name:"sds",
shop_name:"dfgdfg",
address:"hfgdhf",
phone:"dfgfgd",
file:"C:\fakepath\favicon.png",
…
}account_status:"pending"address:"hfgdhf"backup_database:""expiry:"2017-10-19"file:"C:\fakepath\favicon.png"name:"sds"phone:"dfgfgd"shop_name:"dfgdfg"__proto__:{
data:"File is uploaded",
status:200,
statusText:"OK",
headers:{
…
},
config:{
…
},
…
}
component.js
import { saveBasicUser, getOneBasicUser, uploadFile } from '../../actions/basicAction';
class BasicUser extends React.Component {
constructor(props) {
super(props);
this.state = { name: '', phone: '', account_status: '', address: '', shop_name: '', file: [], backup_database: '', expiry: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
//--------------------------------------------------------------------------
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}
//--------------------------------------------------------------------------
handleSubmit(event) {
event.preventDefault();
var userId = this.props.params.id;
var obj = {};
obj["name"] = this.state.name
obj["shop_name"] = this.state.shop_name
obj["address"] = this.state.address
obj["phone"] = this.state.phone
obj["file"] = this.state.file
obj["backup_database"] = this.state.backup_database
obj["expiry"] = this.state.expiry
obj["account_status"] = this.state.account_status
console.log(obj)
this.props.dispatch(saveBasicUser(obj))
}
<form onSubmit={this.handleSubmit} encType="multipart/form-data">
<div className="row">
<div className="col-md-12">
<div className="form-group">
<label>
Name:
</label>
<input type="text" className="form-control" name="name" value={this.state.name} onChange={this.handleChange} placeholder="Zahid Hasan" /> .......................................
..........................................
</div>
<div className="form-group">
<label>File Upload</label>
<div className="form-group">
<label>File Upload</label>
<input type="file" className="form-control" name="file"value={this.state.file}b onChange={this.handleChange} />
</div>
</div>
<div className="btn-group" role="group">
<button type="submit" className="btn btn-success btn-lg">Submit</button>
</div>
action.js
export function saveBasicUser(obj) {
console.log(obj)
return (dispatch) => {
return axios.post('/basic-user/saveUser', {
headers: { 'content-type': 'multipart/form-data' },
obj: obj
}).then(function (res) {
browserHistory.push('/basic-dashboard');
console.log(res)
}).catch(function (err) {
console.log(" err")
console.log(err)
})
}
}
server.js
var multer = require('multer')
var storage = multer.diskStorage({
destination: function(req, file, callback) {
callback(null, './public/uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now()+ path.extname(file.originalname))
}
})
var upload = multer({ storage: storage, limits: {fileSize : 1000000} }).single('file')
app.post('/basic-user/saveUser',function(req,res){
upload(req, res, function(err) {
if(err) {
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
only way to upload file via ajax is use FormData try this.
handleSubmit(event) {
event.preventDefault();
var userId = this.props.params.id;
let formData = new FormData();
formData.append('name', this.state.name);
...
formData.append('file', this.state.file);
...
this.props.dispatch(saveBasicUser(obj))
}
And action file
export function saveBasicUser(obj) {
return (dispatch) => {
return axios.post('/basic-user/saveUser', obj).then(function (res) {
browserHistory.push('/basic-dashboard');
console.log(res)
}).catch(function (err) {
console.log(" err")
console.log(err)
})
}
}
I think you have not created proper destination to upload your image file at server side.
Please check your destination is exist /public/uploads in your server working dir.
Following links will help you on file upload functionality ,
Uploading files with React.js and Node.js
Sample Demo Code
Hopes this will help you !

Resources