I am trying to send formdata from react to express server. When sending json payload, i get what is expected. However, when sending data using formdata.append, i get empty req body.
I tried various solutions posted here for similar problem but nothing seemed to work for me.
Hope someone can help
app.js
require('./database/db')
const express = require('express')
const cors = require('cors')
const userRouter = require('./routes/user')
const menuRouter = require('./routes/menu')
const app = express()
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cors())
app.use(express.static('public'))
app.use(userRouter)
app.use(menuRouter)
app.listen(9000, () => console.log('Server started at port: 9000'))
route i want to call
router.post(
'/addMenu',
[
check('name', 'Menu name is required!').not().isEmpty(),
check('price', 'Price is required!').not().isEmpty(),
check('category', 'Category is required!').not().isEmpty(),
],
verifyAuth,
(req, res) => {
console.log(req.body)
// body is empty here
})
react bootstrap form
import { Component } from 'react'
import axios from '../axios'
import { Link } from 'react-router-dom'
import { Button, Form, Card } from 'react-bootstrap'
export default class AddMenu extends Component {
constructor(props) {
super(props)
this.state = {
name: '',
price: '',
category: '',
image: '',
}
this.inputHandler = this.inputHandler.bind(this)
this.inputHandler = this.inputHandler.bind(this)
this.addMenu = this.addMenu.bind(this)
}
inputHandler = (e) => {
this.setState({
[e.target.name]: e.target.value,
})
}
fileHandler = (e) => {
this.setState({
image: e.currentTarget.files[0],
})
}
addMenu = (e) => {
e.preventDefault()
const { name, price, category, image } = this.state
const data = new FormData()
data.append('name', name)
data.append('price', price)
data.append('category', category)
data.append('file', image)
axios
.post('/addMenu', data)
.then((response) => {
if (response.data.success) {
alert(response.data.menu)
} else {
alert('something went wrong')
}
})
.catch()
}
render() {
return (
<div className='col-lg-12 col-centered' style={{ height: '44rem' }}>
<Card
style={{
width: '20rem',
marginLeft: '420px',
marginTop: '80px',
float: 'left',
height: '34rem',
}}
>
<Card.Img
variant='top'
src='https://image.freepik.com/free-vector/food-delivery-service-fast-food-delivery-scooter-delivery-service-illustration_67394-869.jpg'
/>
<Card.Body>
<Card.Title>Add Menu</Card.Title>
<Card.Text>
Although a great restaurant experience must include great food, a bad restaurant experience can be achieved through bad service alone.
Ideally, service is invisible.
</Card.Text>
<Button as={Link} to='/' variant='info'>
Go to Home
</Button>
</Card.Body>
</Card>
<Card
style={{
width: '22rem',
marginTop: '78px',
float: 'left',
height: '34rem',
}}
>
<Form className='add-menu' onSubmit={this.addMenu}>
<h2>Add Menu</h2>
<Form.Group controlId='formBasicName'>
<Form.Label>Restaurant Name</Form.Label>
<Form.Control
type='text'
name='name'
placeholder='Enter Restaurant Name'
value={this.state.name}
onChange={(event) => this.inputHandler(event)}
/>
</Form.Group>
<Form.Group controlId='formBasicPrice'>
<Form.Label>Enter Price</Form.Label>
<Form.Control type='text' name='price' placeholder='Price' value={this.state.price} onChange={(event) => this.inputHandler(event)} />
</Form.Group>
<Form.Group controlId='formBasicCategory'>
<Form.Label>Enter Category</Form.Label>
<Form.Control
name='category'
type='text'
placeholder='Enter Menu Category'
value={this.state.category}
onChange={(event) => this.inputHandler(event)}
/>
</Form.Group>
<Form.Group controlId='formBasicImage'>
<Form.Label>Enter Category</Form.Label>
<Form.Control name='image' type='file' onChange={this.fileHandler} />
</Form.Group>
<Button className='btn-lg btn-block' variant='info' type='submit'>
Add Menu
</Button>
</Form>
</Card>
<br />
<br />
<br />
</div>
)
}
}
routes/menu implementation
const router = require('express').Router()
const { verifyAuth } = require('../middleware/auth')
const upload = require('../middleware/fileUpload')
const Menu = require('../models/Menu')
const { check, validationResult } = require('express-validator')
// add a menu item
router.post(
'/addMenu',
[
check('name', 'Menu name is required!').not().isEmpty(),
check('price', 'Price is required!').not().isEmpty(),
check('category', 'Category is required!').not().isEmpty(),
],
verifyAuth,
(req, res) => {
console.log(req.body)
if (req.authUser.userType === 'Restaurant') {
const validationErr = validationResult(req)
if (validationErr.isEmpty()) {
let image = null
const { name, price, category } = req.body
if (req.file) {
upload(req, res, (err) => {
if (err) {
response.status(500).json({ success: false, message: err })
} else {
image = req.file.filename
}
})
}
const newMenu = new Menu({ name, price, category, addedBy: req.authUser._id, image })
newMenu
.save()
.then((menu) => res.status(201).json({ success: true, message: 'Menu added', menu }))
.catch((error) => res.status(500).json({ success: false, message: error.message }))
} else {
res.status(400).json({ success: false, errors: validationErr.array() })
}
} else {
res.status(403).json({ success: true, message: 'Insufficient privileges' })
}
}
)
// get all menu items
router.get('/menus', (req, res) => {
Menu.find()
.populate('addedBy', '-_id name')
.then((menus) => res.status(200).json({ success: true, menus }))
.catch((error) => res.status(500).json({ success: false, message: error.message }))
})
module.exports = router
Even in Postman x-www-form-urlencoded sends the data but form-data does not
Form data will get empty object if there is no file given to it via routes like this.
import multer from 'multer';
router.post(
'/addMenu',
multer().single("keyNameForFile"),
[
check('name', 'Menu name is required!').not().isEmpty(),
check('price', 'Price is required!').not().isEmpty(),
check('category', 'Category is required!').not().isEmpty(),
],
verifyAuth,
(req, res) => {
console.log(req.body)
// body is empty here
})
Don't know what cause this behaviour but use form-data when you are sending some file like image doc etc.
You should set the Content-Type of your request header as Content-Type: application/x-www-form-urlencoded this will allow express to access you form data in the body
To set the header in axios you can perform it like this
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
};
and you perform a request to you backend with the header set like this
axios.post('/addMenu', data, config)
.then({ /*...*/});
in your axios request you will need to specify the content type in the headers
of the request. What I usually do also, is specify my agrs as an object for just
for annotation purposes
like this:
axios({
method: 'post',
url: '/addMenu',
data: data,
headers: { 'Content-Type': 'application/json' },
})
.then((response) => {
if (response.data.success) {
alert(response.data.menu)
} else {
alert('something went wrong')
}
})
.catch((error) => {
//handle error
console.log(error);
});
EDIT:
I just noticed that you are trying to send a file as well...haha
to send a file through to express, you will need to get the package called multer to handle file uploads for you
npm i --save multer
then add it when configuring your server
const multer = require('multer');
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
app.use(multer().any());
once you have that done, in your request on the axios side, do it like this:
axios({
method: 'post',
url: '/addMenu',
data: data,
headers: { 'Content-Type': 'multipart/form-data' },
})
.then((response) => {
if (response.data.success) {
alert(response.data.menu)
} else {
alert('something went wrong')
}
})
.catch((error) => {
//handle error
console.log(error);
});
and finally, to handle your files on your server they will show in the request
object like this:
request.files // which will be an array of file objects
please try this...i know its long but i had this issue once and used this solution
As per #ash.io answer BIG NOTICE for MERN stackers! : my case was as it used to return empty object , but when I added (mounted) app.use(express.json()) middleware all sorted out ! Currently MongoDB shows results just fine ! For anyone who interested into quick useForm snippet , here it goes React-useForm boilerplate
Related
I am trying to send the form data of react component to the server through using axios or fetch.
All of the code I wrote failed (in onSubmit).
My server's port is 5000.
I have already set bodyParser in server.js as well.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// React Component
const Voting = ({ history }) => {
const [hasQuery, setQuery] = useState('');
const [formData, setFormData] = useState({
cat: false,
dog: false,
});
const { cat, dog } = formData;
const onChange = e => {
let obj = {};
obj[e.target.name] = e.target.checked;
setFormData(obj);
};
const onSubmit = async e => {
e.preventDefault();
1.
// axios.post('http://localhost:5000/main', { formData }).then(result => {
// console.log(result, 'result');
// });
2.
fetch('http://localhost:5000/main', {
method:'post',
body: formData
})
.then(res => res.json())
.then(data => alert(data.msg));
3.
// fetch('http://localhost:5000/main', {
// method: 'post',
// headers: {
// 'Content-Type': 'application/json; charset=utf-8'
// },
// body: JSON.stringify(formData),
// })
// .then(res => res.json())
// .then(obj => {
// if (obj.result === 'succ') {
// alert('Move on to the next.');
// }
// });
history.push(`/success`);
};
return (
<div>
<p>{hasQuery}</p>
<form
className='mode-container'
onSubmit={onSubmit}
mathod='POST'
action='http://localhost:5000/main'
>
<h3>Choose what you like more</h3>
<div>
<label>
cat
<input
type='radio'
name='cat'
value={cat}
onChange={onChange}
/>
</label>
<label>
dog
<input
type='radio'
name='dog'
value={dog}
onChange={onChange}
/>
</label>
</div>
<button type='submit'></button>
</form>
</div>
);
};
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated,
});
export default connect(mapStateToProps)(Voting);
And below is the code I wrote in node.js. req.body is an empty object.
// Node.js
mainRouter.post(
'/',
(req, _res, _next) => console.log(req, 'req.body'),
);
You are targeting /main in all of your client calls, but on server you only have / route.
Try the following:
axios.post('http://localhost:5000/', { formData }).then(result => {
console.log(result, 'result');
});
Or - change the server route:
mainRouter.post(
'/main',
(req, _res, _next) => console.log(req, 'req.body'),
);
I'm receiving this error: Error: bad content-type header, unknown content-type: text/plain;charset=UTF-8 when trying to upload a photo using Formidable. When I console.log fields and files, I receive two empty objects.
What do I need to change to solve this and upload the photo?
CreatePost.js
const CreatePost = () => {
const [values, setValues] = useState({
title: "",
body: "",
photo: "",
error: "",
createdPost: "",
formData: "",
});
const { user, token } = isAuthenticated();
const {
title,
body,
error,
createdPost,
formData,
} = values;
const handleChange = (name) => (event) => {
const value = name === "photo" ? event.target.files[0] : event.target.value;
setValues({ ...values, [name]: value, formData: new FormData() });
};
const clickSubmit = (event) => {
event.preventDefault();
setValues({ ...values, error: "" });
createPost(user._id, token, formData).then((data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
title: "",
body: "",
photo: "",
createdPost: data.title,
});
}
});
};
const newPostForm = () => (
<form className="mb-3" onSubmit={clickSubmit}>
<h4>Post Photo</h4>
<div className="form-group">
<label className="btn btn-secondary">
<input
onChange={handleChange("photo")}
type="file"
name="photo"
accept="image/*"
/>
</label>
</div>
<div className="form-group">
<label className="text-muted">Title</label>
<input
onChange={handleChange("title")}
type="text"
className="form-control"
value={title}
/>
</div>
<div>
<label>Post body</label>
<textarea
onChange={handleChange("body")}
value={body}
/>
</div>
<button>Create Post</button>
</form>
);
const showError = () => (
<div
style={{ display: error ? "" : "none" }}>
{error}
</div>
);
const showSuccess = () => (
<div
style={{ display: createdPost ? "" : "none" }}>
<h2>{`${createdPost} is created!`}</h2>
</div>
);
return (
<div>
<div>
{showSuccess()}
{showError()}
{newPostForm()}
</div>
</div>
);
};
export default CreatePost;
API request (create post)
export const createPost = (userId, post, token) => {
return fetch(`${API}/blog/post/${userId}`, {
method: 'POST',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`
},
body: post
})
.then(response => {
return response.json();
})
.catch(err => {
console.log(err);
});
};
controllers/posts.js
exports.create = (req, res) => {
let form = new formidable()
form.keepExtensions = true
form.parse(req, (err, fields, files) => {
if(err) {
console.log(err)
return res.status(400).json({
error: 'Image could not be uploaded'
})
}
const { title, body } = fields
console.log(fields)
if (!title || !body) {
return res.status(400).json({
error: "All fields are required"
})
}
let post = new Post(fields)
if(files.photo) {
if (files.photo.size > 1000000) {
return res.status(400).json({
error: "Image should be less than 1MB in size."
})
}
post.photo.data = fs.readFileSync(files.photo.path)
post.photo.contentType = files.photo.type
}
post.save((err, result) => {
if(err) {
return res.status(400).json({
error: errorHandler(err)
})
}
res.json(result)
})
})
}
exports.photo = (req, res, next) => {
if (req.post.photo.data) {
res.set('Content-Type', req.post.photo.contentType)
return res.send(req.post.photo.data)
}
next()
}
this has been up for a long time, I bet you already solve it.
If somebody stumbles with this question as I did, what worked for me was adding .IncomingForm() method on the new form in post controller file, like this:
let form = new formidable.IncomingForm();
I'm trying to update the posts. The PUT request in the back end works fine, returning 200 and updates posts when tested on Postman however when I try to update a post in the front end (react), I'm not receiving any errors but the updated post isn't being updated on submit and the updated fields (title and body) are null. The updated values are null when I console.log(data) in the front end which is why they aren't being sent to the back end but they are shown correctly in post.
Why are the updated values null inside data? How can I update the post with the new values instead of getting null?
data:
post:
Updated code: Frontend
const EditPost = ({match}) => {
const [values, setValues] = useState({
title: "",
body: "",
error: ""
});
const [post, setPost] = useState({});
const { user, token } = isAuthenticated();
const {
title,
body,
error,
} = values;
const init = (id) => {
read(id).then(data => {
if (data.error) {
setValues({...values, error: data.error})
} else {
setValues({...values,
title: data.title,
body: data.body,
})
setPost({title: values.title, body: values.body})
}
})
}
useEffect(() => {
const id = match.params.id;
init(id);
}, []);
useEffect(() => {
setPost({...values });
}, [values.title, values.body]);
const handleChange = (name) => (event) => {
setValues({ ...values, [name]: event.target.value });
};
const clickSubmit = (event) => {
event.preventDefault();
setValues({ ...values, error: "" });
editPost(match.params.userId, match.params.id, token, post).then((data) => {
if (data.error) {
setValues({ ...values, error: data.error });
} else {
setValues({
...values,
title: "",
body: "",
error: false,
});
console.log(post)
console.log(data)
}
});
};
const newPostForm = () => (
<form onSubmit={clickSubmit}>
<div>
<input
onChange={handleChange("title")} type="text"
name="title"
value={title}
/>
</div>
<div className="form-group">
<textarea
onChange={handleChange("body")}
value={body} name="body"
/>
</div>
<button type="submit">Publish</button>
</form>
);
const showError = () => (
<div
style={{ display: error ? "" : "none" }}>
{error}
</div>
);
return (
<div>
{showError()}
{newPostForm()}
</div>
);
};
export default EditPost;
export const editPost = (userId, id, token, post) => {
return fetch(`${API}/${userId}/${id}/edit`, {
method: 'PUT',
headers: {
Accept: 'application/json',
Authorization: `Bearer ${token}`
},
body: JSON.stringify(post)
})
.then(response => {
return response.json();
})
.catch(err => console.log(err));
};
postsByUser.js
<Link className="mypost_btn edit_btn" to={`/${_id}/${post._id}/edit`}>
Edit
</Link>
Backend code
exports.edit = (req, res) => {
if (!ObjectID.isValid(req.params.id))
return res.status(400).send(`ID is not valid: ${req.params.id}`)
const {title, body} = req.body
const updatedPost = {title, body }
Post.findByIdAndUpdate(req.params.id, {
$set: updatedPost
}, {new:true}, (error, data) => {
if (error) {
return error
} else {
res.send(data)
console.log(data)
}
})
}
Your problem lies here:
editPost(match.params.userId, match.params.id, token, post)
post is not defined.
Since post is not defined, no data is passed. Hence title and body equal to null. What you will need to do is, assuming from what I'm seeing on your code, is to define a state variable called post. I think you intended to do that:
const [post, setPost] = useState({values.title, values.body});
Then ensure that your post is updated whenever your values change using useEffect(),
useEffect(() => {
setPost({...values });
}, [values.title, value.body]);
So by the time you call your editPost() http-put-method, then post has a value. And it should work.
in EditPost.js editPost(match.params.userId, match.params.id, token).then((data) => { here you are missing the 4th arg which is the "post" it self you send to be updated
I'm making a script to add Q&A in react.js and mongodb. I have a problem when pressing a button creates the following errors
Failed to load resource: the server responded with a status of 404 (Not Found)
create-quest.component.js:40
Object
data: "↵↵↵↵Error↵↵↵Cannot POST /create↵↵↵"
status: 404
statusText: "Not Found"
headers: {access-control-allow-origin: "*", connection: "close", content-length: "146", content-security-policy: "default-src 'none'", content-type: "text/html; charset=utf-8", …}
config: {url: "http://localhost:3000/create", method: "post", data: "{"title":"aaa","content":"aaa"}", headers: {…}, transformRequest: Array(1), …}
request: XMLHttpRequest {readyState: 4, timeout: 0, withCredentials: false, upload: XMLHttpRequestUpload, onreadystatechange: ƒ, …}
proto: Object
my code is:
import React, { Component } from 'react';
import axios from 'axios';
export default class CreateQuest extends Component {
constructor(props) {
super(props)
this.onChangeTitle = this.onChangeTitle.bind(this);
this.onChangeContent = this.onChangeContent.bind(this);
this.onSubmit = this.onSubmit.bind(this);
this.state = {
title: '',
content: ''
}
}
onChangeTitle(e) {
this.setState({ title: e.target.value })
}
onChangeContent(e) {
this.setState({ content: e.target.value })
}
onSubmit(e) {
e.preventDefault()
const questionObject = {
title: this.state.title,
content: this.state.content
};
axios.post('http://localhost:3000/create', questionObject)
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error.response)
});
this.setState({ title: '', content: '' })
}
render() {
return (
<div className="wrapper">
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Add title</label>
<input type="text" value={this.state.title} onChange={this.onChangeTitle} className="form-control" />
</div>
<div className="form-group">
<label>Add content</label>
<input type="text" value={this.state.content} onChange={this.onChangeContent} className="form-control" />
</div>
<div className="form-group">
<input type="submit" value="Create Question" className="btn btn-success btn-block" />
</div>
</form>
</div>
)
}
}
I am beginner in node react and mongo and I dont understand where is error
this is my routes code
module.exports = (app) => {
const questions = require('../controllers/question.controller.js');
const answers = require('../controllers/answer.controller.js');
// Create a new Note
app.post('/questions', questions.create);
app.post('/questions/:questionId/answers', answers.create);
// Retrieve all Notes
app.get('/questions', questions.findAll);
// Retrieve a single Note with noteId
app.get('/questions/:questionId', questions.findOne);
app.get('/questions/:questionId/answers', questions.findOne); // find answers by question id
// Update a Note with noteId
app.put('/questions/:questionId', questions.update);
// Delete a Note with noteId
app.delete('/questions/:questionId', questions.delete);
}
let mongoose = require('mongoose'),
express = require('express'),
router = express.Router();
let question = require('../models/question.model');
router.route('/create').post((req, res, next) => {
questions.create(req.body, (error, data) => {
if (error) {
return next(error)
} else {
console.log(data)
res.json(data)
}
})
});
router.route('/').get((req, res) => {
questions.find((error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
router.route('/edit/:id').get((req, res) => {
questions.findById(req.params.id, (error, data) => {
if (error) {
return next(error)
} else {
res.json(data)
}
})
})
router.route('/update/:id').put((req, res, next) => {
questions.findByIdAndUpdate(req.params.id, {
$set: req.body
}, (error, data) => {
if (error) {
return next(error);
console.log(error)
} else {
res.json(data)
console.log('Question updated successfully !')
}
})
})
router.route('/delete/:id').delete((req, res, next) => {
questions.findByIdAndRemove(req.params.id, (error, data) => {
if (error) {
return next(error);
} else {
res.status(200).json({
msg: data
})
}
})
})
module.exports = router;
my app.js
import React, { Component } from 'react'
import { BrowserRouter as Router, Route } from 'react-router-dom'
import Navbar from './components/Navbar'
import Landing from './components/Landing'
import Login from './components/Login'
import Register from './components/Register'
import Profile from './components/Profile'
import Question from './components/Question'
import Answers from './components/Answer'
import CreateQuest from './components/create-quest.component'
class App extends Component {
render() {
return (
<Router>
<div className="App">
<Navbar />
<Route exact path="/" component={Landing} />
<div className="container">
<Route exact path="/register" component={Register} />
<Route exact path="/login" component={Login} />
<Route exact path="/profile" component={Profile} />
<Route exact path="/questions" component={Question} />
<Route exact path="/create" component={CreateQuest} />
<Route exact path="/answers" component={Answers} />
</div>
</div>
</Router>
)
}
}
export default App
This is an issue with your backend code, rather than your frontend code. The line Cannot POST /create is the key information here. Look at where you defined your route handlers and, if you're using Express, make sure you have something like app.post('/create', (req, res) => { /** some code here **/ }
Edit:
As you have included some of your code, I'm guessing you either didn't tell your Express to app use the router, or you gave it a mount point that is not the root ('/'), so it's looking for your requests as /<mount point>/create rather than /create. Make sure you have a line in your backend app/server file saying app.use(router) and notice that no mount path was provided, so it will look for requests on /create.
However, in your routes file, you are trying to export both the routes function as well as your router, but you are overwriting the module.exports object, rather than exporting them both. You probably want to change those lines to:
module.exports.routes = (app) => ...
and
module.exports.router = router
i have been trying to make a post request from my react native app on an android emulator but the object that i am sending in the body of the request is being vvalued as undefined,been trying alot to solve this issue but no success. Please help me
here is the code to my form in the app known as "API.js" its named so just for testing the API endpoints
import React, { Component } from "react";
import {
Text,
TextInput,
View,
TouchableHighlight,
StyleSheet,
Button,
FormData
} from "react-native";
import Permissions from "react-native-permissions";
import ImagePicker from "react-native-image-crop-picker";
import axios from "axios";
var styles = StyleSheet.create({});
var msg = "Select Image";
var data;
export default class API extends Component {
constructor(props) {
super(props);
this.state = {
name: "",
price: "",
size: "",
description: "",
image: "",
popularity: ""
};
}
FormDataFunc() {
let form = new FormData();
form.append("name", this.state.name);
form.append("price", this.state.price);
form.append("size", this.state.size);
form.append("description", this.state.description);
form.append("image", this.state.image);
form.append("popularity", this.state.popularity);
return form;
return form;
}
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
Submit() {
axios({
method: "post",
url: "http://192.168.0.102:3000/products",
data: this.FormDataFunc,
headers: {
Accept: "application/json",
"Content-Type": "application/x-www-form-urlencoded"
},
body: this.FormDataFunc
})
.then(() => {
console.log("DONE!");
this.props.navigation.navigate("offersScreen");
})
.catch(err => {
console.log(err);
console.log(this.FormDataFunc);
});
}
componentDidMount() {
Permissions.check("photo").then(response => {
// Response is one of: 'authorized', 'denied', 'restricted', or 'undetermined'
console.log(response);
});
}
render() {
const image = () => {
ImagePicker.openPicker({
multiple: false,
includeBase64: true
}).then(images => {
console.log(images);
this.setState({
images: { data: `\`${images.mime}\`;base64,\`${images.data}\`` }
});
console.log(this.state.images);
msg = "Selected";
});
};
return (
<View>
<TextInput placeholder="Name" name="name" />
<TextInput placeholder="Price" name="price" />
<TextInput placeholder="Size" name="size" />
<TextInput placeholder="Description" name="description" />
<TouchableHighlight onPress={image} name="image">
<Text>{msg}</Text>
</TouchableHighlight>
<TextInput placeholder="Popularity" name="popularity" />
<TouchableHighlight title="Submit" onPress={this.Submit}>
<Text>Send</Text>
</TouchableHighlight>
</View>
);
}
}
here is the code to my backend route "product.js" which recieves the request(node.js and express)
const express = require("express");
const router = express.Router();
const bodyParser = require("body-parser");
const path = require("path");
const cloudinary = require("cloudinary");
const mongoose = require("mongoose");
//Product Model
const product = require("../models/product").product;
router.use(bodyParser.json());
//GET route
router.get("/", (req, res) => {
product.find().then(product => res.json(product));
});
// POST route
cloudinary.config({
cloud_name: "cloud222",
api_key: "783935981748815",
api_secret: "uY47vBS1rI2x5jvFtnXQIjMMqU0"
});
router.post("/", (req, res) => {
//MISC//
let imageUrl;
console.log("starting");
//MISC//
//CLOUDINARY UPLOAD
cloudinary.v2.uploader.upload(req.body.image, (error, result) => {
if (error) {
console.log(error);
console.log(`${req.body.image}`);
} else {
imageUrl = result.secure_url;
//MONGO UPLOAD
var productv = {
name: req.body.name,
price: req.body.price,
size: req.body.size,
description: req.body.description,
image: imageUrl,
popularity: req.body.popularity
};
const productvar = new product(productv);
productvar
.save()
.then(product => console.log(product))
.then(product => res.json(product))
.catch(err => console.log(err));
}
});
//END//
});
module.exports = router;
the data is being logged as undefined and therefore the request doesnt get a response
I think the problem is that you have created a FormData and wanted to post it, but the headers you added is "application/json". You should change it:
headers: {
'content-type': 'multipart/form-data',
'Accept':'multipart/form-data',
},
Hope it works for you.
Problem solved
Had to use onChangeText = instead of onChange as onChange does not return a string