reactjs - Uploading an image to mongodb using Multer with Express and Axios -
i trying make small application allows admin user enter name, price , image of product can viewed on page. details sent mongo database performed via axios post front end. can send name , price no problem can seen on front end dynamically, however, unable send image mongo database i've been trying achieve quite time.
i using multer , axios try , sent file on application react app. think problem "req.file" within end of application. code below endpoint:
api.js
var express = require('express'); var bodyparser = require('body-parser'); var cors = require('cors') var app = express(); var mongodb = require('mongodb'); var path = require('path'); var fsextra = require('fs-extra'); var fs = require('fs') var util = require('util') var multer = require('multer') var upload = multer( {dest: __dirname + '/uploads'} ) var ejs = require('ejs') const mongoclient = require('mongodb').mongoclient; app.use(express.static(path.resolve(__dirname, '../react', 'build'))); app.get('*',(req,res)=>{ res.sendfile(path.resolve(__dirname, '../react', 'build', 'index.html')); }); console.log(__dirname) app.use(cors()); app.use(bodyparser.urlencoded({ extended: true })); app.use(bodyparser.json()); app.use(express.static(path.join(__dirname, 'public'))); app.set('views', __dirname); app.engine('html', require('ejs').renderfile); app.set('view engine', 'html'); var db; mongodb.mongoclient.connect('mongodb://<mydbdetails>', (err, database) => { if (err) { console.log(err) process.exit(1); } db = database; console.log('database connection ready') }); var server= app.listen(process.env.port || 8082, function () { var port = server.address().port; console.log("app running on port", port); }); app.post('/api/submitimage', upload.single('inputform'), function(req,res){ var file = req.body.file if (file == null) { // if submit accidentally clicked no file selected... //res.render('admin', { title:'please select picture file submit!'}); res.send({success: false, message: "dsfdsg"}) console.log('there no file present') console.log(req.file,'file') } else{ // read img file tmp in-memory location var newimg = fs.readfilesync(req.files.path); console.log(newimg,'details of new image') // encode file base64 string. var encimg = newimg.tostring('base64'); console.log(encimg,'kdfjndodj') // define new document var newitem = { description: req.body.description, contenttype: req.file.mimetype, size: req.files.size, img: buffer(encimg, 'base64') }; db.collection('products').insert(newitem, function(err, result){ if(err) { console.log(err) } var newoid = new objectid(result.ops[0]._id); fs.remove(req.file.path, function(err) { if (err) { console.log(err) }; res.render('./src/components/admincontainer.js', {title:'thanks picture!'}); }); }) } })
the next code how trying send on using axios:
import axios 'axios'; class productsapi { static submitproduct(name,prices,callback){ axios.post('http://localhost:8082/api/submitproduct', {name: name, prices: prices}) .then( response => { callback(response) }) } static viewname(callback){ axios.post('http://localhost:8082/api/retrievename') .then( response => { return callback(response) }) } static viewprice(callback){ axios.post('http://localhost:8082/api/retrieveprice') .then( response => { return callback(response) }) } static viewproducts(callback){ axios.post('http://localhost:8082/api/retrieveproducts') .then( response => { return callback(response) }) } static submitimages(image,callback){ axios.post('http://localhost:8082/api/submitimage',{image: image}) .then( response => { return callback(response) console.log('response has been made,', image,'has been recieved axios') }) } } export default productsapi;
the last file how trying send file database using react event handlers:
import react, { component } 'react' import '../app.css' import appheader './appheader.js' import productsapi '../api/axios.js' const admincontainer = () => { return( <div> <appheader /> <formcontainer /> </div> ) } class formcontainer extends component{ constructor(props){ super(props); this.state={ file: '', inputname: '', inputprice: '', image: '' }; this.handlenamechange = this.handlenamechange.bind(this); this.handlepricechange = this.handlepricechange.bind(this); this.handlesubmit = this.handlesubmit.bind(this); this.sendname = this.handlesubmit.bind(this); } handlenamechange(e){ console.log(e.target.value) this.setstate({ name : e.target.value, }) } handlepricechange(e){ console.log(e.target.value) this.setstate({ prices : e.target.value }) } sendname(e){ this.setstate({ inputname: e.target.value, inputname:e.target.value }) } handlesubmit(e){ e.preventdefault(); console.log('attempting access axios...') productsapi.submitproduct(this.state.name, this.state.prices, resp => { console.log('response has been made', resp) //if error message, add state , show error message on front end this.setstate({ inputname:this.state.name, inputprice:this.state.prices },function(){ console.log(resp,'this resp') console.log('axios has send ',this.state.name,' database') }); }) console.log(this.state.prices,'this new price') console.log(this.state.name,'this new name') productsapi.submitimages(this.state.image, response => { console.log('axios has been notified submit image...') this.setstate({ image: this.state.image },function(){ console.log('image submission axios response details follows: ', response) console.log(this.state.image, ': has been sent db') }) }) } render(){ return( <div> <h2>add new product shop</h2> <div classname='formwrapper'> <div classname='center'> <form name='inputform' enctype='multipart/form-data' method='post'> <label> name: <input value = {this.state.name} onchange={this.handlenamechange} type="text" placeholder='name' /><br /> price: <input value = {this.state.prices} onchange={this.handlepricechange} type='text' /><br /> </label> <label> choose image: <input classname='imginsert' name ='inputform' type='file'/> </label> <div> <img classname = 'previewimage' value={this.state.image}/> </div> <button classname='btn updatebtn' onclick={(e) => this.handlesubmit(e)}>submit</button> </form> </div> </div> </div> ) } } export default admincontainer
common errors getting when trying debug
typeerror: cannot read property 'path' of undefined."
and "file" being undefined.
when using multer save images need make sure image comes server form data. because multer requires multipart/form-data encoding not when submitting form ajax request unless if make happen. can using formdata object. here example of being used. hope helps.
Comments
Post a Comment