Reputation: 11
I am trying to post form data from react to node backend, How to do thtat ? my React code is :
import fetch from 'isomorphic-fetch';
export function createBio (data) {
console.log(data);
return fetch('http://localhost:3001/user/create', {
method: 'POST',
mode: 'no-cors',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
}
}).then(res => {
return res;
}).catch(err => console.log(err));
}
My NodeJs code
router.post('/create', (req,res,) => {
var user = new User({title: req.params.title || "Untitled Note", body: req.params.body});
user.save();
});
How to retrieve data
Upvotes: 1
Views: 1786
Reputation: 798
My best way, start create file api.js
import axios from "axios";
export default {
user: {
createBio: data => axios.post(`${process.env.API_HOST}/user/create`, {data}).then(res => res),
}
}
and then you can call function createBio from your component or action if you use redux,
if you get problem Access-Control-Allow-Origin use CORS
Upvotes: 1
Reputation: 31
req.param()
searches the url path, body, and query string of the request (in that order) for the specified parameter. If no parameter value exists anywhere in the request with the given name
, it returns undefined
, or the optional defaultValue
if specified.
url path parameters (
req.params
)
e.g. a request /create/4
to route /create/:id
has url path params req.params.id
:id this id you can change anything you want, but you should add ":" before your parameter
body parameters (
req.body
)
e.g. a request with a parseable body (e.g. JSON, url-encoded, or XML) has body parameters equal to its parsed value
if you want to get the title, you can write req.body.title
For your case, I recommend you use req.body
Your back-end API
//http://localhost:3001/user/create
router.post('/create', (req,res) => {
const user = new User(
{
title: req.body.title ===null ? 'Untitled Note' : req.body.title,
text: req.body.text
});
user.save();
});
You should determine what value your data include
data = {
title: '?',
text: '?'
};
Your Fetch
import fetch from 'isomorphic-fetch';
export function createBio (data) {
console.log(data);
fetch('http://localhost:3001/user/create', {
method: 'POST',
mode: 'no-cors',
body: JSON.stringify(data),
headers: {
'Content-Type': 'application/json',
}
}).then(res => {
return res;
}).catch(err => console.log(err));
}
Make sure of your path is right
Any way, I use 'axios' to retrieve data
router.post('/'),
(req, res) => {
const newPost = new Post({
eventTitle: req.body.eventTitle,
eventText: req.body.eventText
});
newPost.save().then(post => res.json(post));
});
axios
const postData = {
title: '?',
text: '?'
};
axios
.post('/api/posts', postData)
.then(res => console.log(res))
.catch(err => console.log(err));
Get params
**!But this title should be assigned a value. not a null value**
router.post('/:title'),
(req, res) => {
const newPost = new Post({
eventTitle: req.params.title,
eventText: req.body.eventText
});
newPost.save().then(post => res.json(post));});
const postData = {
title: '?',
text: '?'
};
axios
.post(`/api/posts/${postData.title}`, postData.text)
.then(res => console.log(res))
.catch(err => console.log(err));
If you have any questions about fetch, you can use this https://developer.mozilla.org/en-US/.
I hope this is useful for you. Actually, I never used fetch, but axios is same with it.
PS: you should add this for your server.js to get value from the client side. Node.js body parsing middleware. Parse incoming request bodies in a middleware before your handlers, available under the req.body property.
const bodyParser = require('body-parser');
// for parsing application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
// for parsing application/json
app.use(bodyParser.json());
Last answer for your comment and your issue.
First, you should add proxy
to your client side package.json
You cannpm I concurrently
to run your server and client simultaneously
Your package.json should include --- I did't create a server json, this may a wrong format. But just a test. The part of ** should be written in the server package.json file! If you don't want to use it, you can just focus on the code, it will fix your problem.
{
"name": "react",
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"body-parser": "^1.18.3",
"concurrently": "^4.0.1",
"express": "^4.16.4",
"fetch": "^1.1.0",
"node-fetch": "^2.2.0",
"react": "^16.4.2",
"react-dom": "^16.4.2",
"react-scripts": "1.1.4",
"isomorphic-fetch": "^2.2.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
**"server": "node server.js",**
**"client": "npm start",**
**"dev": "concurrently \"npm run server\" \"npm run client\"",**
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:5000"
}
npm I node-fetch
at client side
import React, {Component} from 'react';
//import axios from 'axios';
//import fetch from 'node-fetch';
import fetch from 'isomorphic-fetch';
class SendMessage extends Component {
constructor(props) {
super(props);
this.state = {
title: '',
text: ''
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
onSubmit(e){
e.preventDefault();
const newUser = {
title: this.state.title,
text: this.state.text,
};
// axios.post('/users/create', newUser)
// .then(res => console.log(res))
// .catch(err => console.log(err));
fetch('/users/create', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(newUser)
}).then(res=>res.json())
.then(res => console.log(res));
}
onChange(e){
this.setState({[e.target.name]:e.target.value})
}
render() {
return (
<div>
<form onSubmit={this.onSubmit}>
<input type="text" name='title' onChange={this.onChange} value={this.state.title} placeholder="title"/>
<input type="text" name='text' onChange={this.onChange} value={this.state.text} placeholder="text"/>
<input type="submit" value="Submit"/>
</form>
</div>
);
}
}
export default SendMessage;
Server side server.js
const express = require ('express');
const bodyParser = require('body-parser');
//import route
const users = require('./route');
var app = express();
//Body parser middleware
app.use(bodyParser.urlencoded({extended: false}));
app.use(bodyParser.json());
// Use routes
app.use('/users', users);
const port = process.env.PORT || 5000;
app.listen(port, () => console.log(`Server running on port ${port}`));
Server side route.js
const express = require('express');
const router = express.Router();
router.post('/create', (req,res) => {
console.log(req.body);
const user =
{
title: req.body.title ===null ? 'Untitled Note' : req.body.title,
text: req.body.text
};
res.status(200).json(user);
});
module.exports = router;
Upvotes: 3
Reputation: 7496
You can use body-parser middleware to parse the body of your request
in your server.js:
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.json({limit: '10mb'}));
and supposing you send an object to the server like:
let data = {
myProp: 'myVal1'
}
You can then get it in the request:
router.post('/create', (req,res,) => {
let value = req.body.myProp;
console.log('value in body: ' + value);
// execute...
});
This will log:
value in body: myVal1
I would also strongly recommend using Axios for your requests instead of fetch, and read my answer in this post where I discuss some differences and how to implement axios if you are using fetch already. This way you don't need to stringify your data for example, and you solve other issues discussed there.
If you use Axios (with async/await), set your request object like so:
let reqObj = {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
url: 'http://localhost:3001/user/create',
data: {
myProp: 'myVal1'
}
};
And send the request to axios with:
let response = await axios(reqObj);
Upvotes: 0
Reputation: 477
You're sending a request to '/user/create' when your Node.js server is listening on 'create'. Try changing
fetch('http://localhost:3001/user/create'
to
fetch('http://localhost:3001/create'
Upvotes: 1