I am currently having a problem with React and Express JS form submit function. It seems like my nodeJS running on port 5000 is receiving an empty object from my ReactJS running on port 8080 using fetch method.
React : Contact.js
handleSubmit(e)
{
e.preventDefault();
var data = {
name: this.state.name,
contact: this.state.contact,
email: this.state.email,
message: this.state.message,
}
var url = 'http://localhost:5000/api/insertUsers';
fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
mode: 'no-cors',
body: JSON.stringify(data),
})
.catch((error) => {
console.log(error);
});
}
NodeJS : server.js
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
app.listen(5000, () => {
console.log('listening on port 5000');
});
Change the order of bodyparser middleware like this.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
You are sending a request with the content-type of 'application/json' but express is expecting a content-type of 'text/json'. Usually, when req.body is empty content-type is the first suspect you should be looking at.
I am ashamed that I struggled with this for hours. I still haven't gotten it to work with file uploads.
But I did get it to work with a normal form by encoding JSON and sending that along with axios, instead of fetch
My js code
var data = {
id: this.state.id,
}
console.log('data',data)
var bodyFormData = new FormData();
bodyFormData.set('id', this.state.id);
var url = ' http://localhost:3000/get-image-by-id';
console.log("bodyFormData: ", bodyFormData);
axios({
method: 'post',
url: url,
data: data,
// headers: {'Content-Type': 'multipart/form-data' }
headers: {'Content-Type': 'application/x-www-form-urlencoded' }
})
.then(function (response) {
//handle success
console.log(response);
})
.catch(function (response) {
//handle error
console.log(response);
});
Form Code
<form method="POST" onSubmit={this.handleSubmit} >
<label>
Transaction ID
<input
type="text"
name="id"
value={this.state.id}
onChange={this.handleInputChange}
/>
</label>
<button type="submit">Submit</button>
</form>
```
EDIT
fetch(url, {
method: 'POST',
body: JSON.stringify(data),
mode: 'no-cors'
}).then((result)=>{
console.log("output" + result.json());
})
.catch((error) => {
console.log(error);
});
EDIT 2
for backend, install cors and add the following lines before route.
var cors = require('cors')
app.use(cors())
EDIT 3
perform npm install morgan then copy these lines inside the code
var morgan = require('morgan');
app.use(morgan('dev'));
I didn't look at your code close enough. My bad
app.post('/api/insertUsers', function(req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:\n')
res.end(JSON.stringify(req.body, null, 2))
});
Should be
app.post('/api/insertUsers', function(req, res) {
res.json(req.body)
});
try using axios instead of fetch
I rewrote ur code like this and it works perfectly
server
const express = require('express');
const { Client } = require('pg');
const bodyParser = require('body-parser');
const app = express();
const cors = require("cors");
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.post('/api/insertUsers', function(req, res) {
// console.log(req);
console.log(req.body);
res.send(req.body);
});
app.listen(3001, () => {
console.log('listening on port 3001');
});
react (ensure you have axios installed)
handleSubmit(e){
e.preventDefault();
var data = {
name: "zadiki",
contact: "0702002109",
email: "zadiki",
message: "test",
}
console.log("wow");
var url = ' http://localhost:3001/api/insertUsers';
axios.post(url,data)
.then(response=>console.log(response))
.catch(e=>console.log(e))
}
Hello I ended up getting mine working after I ran into the same problem.
I noticed your react code has "mode: 'no-cors'," that was causing problems with mine so I removed it.
-------- Below is my handle submit code for React ------------
const handleSubmit = (event) => {
event.preventDefault();
const url = "http://localhost:3001/register"
const options = {
method: "POST",
body: JSON.stringify(formData),
headers: {
"Content-Type": "application/json"
}
}
fetch(url, options)
.then(res => res.json())
.then(res => console.log(res))
}
I used express.json instead of bodyParser. You also had a typo in your express code, it should say res.send instead of res.end
--------- Below is my Node Express Code -----------
const express = require('express');
const app = express();
const cors = require('cors');
const multer = require('multer');
// Middlewares
app.use(cors({ origin: 'http://localhost:3000', }))
app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(multer().array());
app.post('/register',(req, res) => {
console.log(req.body)
res.status(200)
.json({status:"Success", data:{body: req.body })
});
app.listen(3001, () => console.log(`Running on 3001`))
I was able to send form data using postman and react using the code above. Feel free to change it to accommodate your needs.
Related
Im trying to implement a simple fetch request to the server as follows
<input type="text" id="usersearchfield" onKeyUp={(e)=>sendData(e.target.value)}/>
function sendData (input){
fetch('/api/user/userSearch',{
method:'POST',
headers:{'Accept': 'application/json',
'Content-Type': 'multipart/form-data'},
body: JSON.stringify({username: input})
})
.then(res =>res.json)
.then(data =>{
let input = data.input
console.log("input is:",input)
})
}
This is my server's side index.js
app.use(express.json());
app.use(express.urlencoded({ extended: true}));
app.use("/api/user" , userRouter);
routes
//serach user
router.post('/userSearch',userController.userSearch)
controller
const userSearch = async (req, res) => {
const input =req.body.username
console.log("SERVER GOT",input)
let search = await User.find({username: {$regex: new RegExp('^'+input+'.*','i')}}).exec()
search = search.slice(0,10)
res.send({input:search})
console.log("INPUT IS ",input)
}
When i try to execute this code i get POST http://localhost:3000/api/user/userSearch 404 (Not Found)
what im missing?
I am trying to post the data from react (front end) to nodejs server using axios api call, the url is hit and executes properly, but the the sent data is empty
Node code*
const express = require("express");
const bodyParser = require('body-parser');
const cors = require("cors");
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
let corsOptions = {
origin: "*",
optionsSuccessStatus: 200,
};
app.use(cors(corsOptions));
app.post("/signin",function(request,response,next){
console.log(request);
console.log(request.body);
response.json({});
})
app.listen(4000, "localhost", function () {
console.log("App is listening at port 4000");
});
React Method
onSignin=function(event){
let data = new FormData();
data.append("signinEmail",this.state.signinEmail);
axios({
method:"post",
url:"http://localhost:4000/signin",
data:data,
headers:{
'Content-Type':'multipart/form-data'
}
}).then((res)=>{
console.log(res);
})
}
any help is appreciated.
If you don't need to upload a file in /signin API, you can use 'Content-Type':'application/json' and send a JSON object to the server.
onSignin=function(event){
// data send to server
let data = {
signinEmail : this.state.signinEmail
};
axios({
method:"post",
url:"http://localhost:4000/signin",
data:data,
headers:{
'Content-Type':'application/json'
}
}).then((res)=>{
console.log(res);
})
}
Im building an express instance for the first time and ive run into an issue where everything works locally, but when deployed sending a post request to the route responds:
Failed to load resource: the server responded with a status of 405
(Not Allowed)
Ive included the relevant code below:
server/index.js
const express = require('express');
const bodyParser = require('body-parser')
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
const routes = require('./routes')(express)
require('./db')
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT || 8080);
app.use('/', routes);
routes/index.js
var mongoose = require("mongoose");
const randomId = require('random-id');
const Submissions = require('../api/Submissions')
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
router.route('/submission')
.post((req, res) => {
let newSubmission = new Submissions(req.body);
newSubmission._id = randomId(17, 'aA0');
// Save the new model instance, passing a callback
newSubmission.save(function(err,response) {
if (err) {
console.log(err)
} else {
res.setHeader('Content-Type', 'application/json');
res.json({'success':true})
}
// saved!
})
});
return router;
}
client.js
let submission = {
name: this.state.newSubmission.name.trim(),
body: this.state.newSubmission.body.trim(),
email: this.state.newSubmission.email.trim(),
};
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(submission),
};
fetch("/submission", requestOptions)
.then((response) =>
response.json().then((data) => ({
data: data,
status: response.status,
}))
)
.then((res) => {
if (!res.data.success) {
notifier.warning('Failed to submit');
} else {
notifier.success('Submission successful');
}
});
I try to send data from my client to my server. For that, i use React with NextJS, because you have the server and client-side in one app.
I use the following handleSubmitFunction:
handleSubmit() {
const email = this.state.email;
fetch('/', {
method: 'POST',
body: email,
});
}
and this is my server.js file in the located in / at my project
const express = require('express')
const next = require('next')
const bodyParser = require('body-parser')
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare()
.then(() => {
const server = express()
//parse application
server.use(bodyParser.urlencoded({ extended: false}))
//parse application/json
server.use(bodyParser.json())
server.post('/', (req, res) => {
console.log(req.body.email);
res.end("success!");
})
server.get('*', (req, res) => {
return handle(req, res)
})
server.listen(3000, (err) => {
if (err) throw err
console.log('> Ready on http://localhost:3000')
})
})
.catch((ex) => {
console.error(ex.stack)
process.exit(1)
})
When the handleSubmit Function is running, i get the following Output from the Server Console:
Cannot read property 'email' of undefined
Where exactly is my mistake?
I have little experience in node JS environments. I would be very grateful if you could show me concrete solutions. Thank you for your replies.
It seems you have to parse header and JSON.stringify the email.
fetch('/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({email:email}),
}).then((res)=> console.log('Worked'))
I'm working on my first mean stack application and running in to a problem. I have a Blog model and I'm trying to assign the properties from the req object but its undefinded. When I do a console log of the req.body it looks like this:
{ '{"title":"some title", "body":"some body", "createdBy":" "created By"}':''}
but when I log the values out individually like console.log(req.body.title) its undefined. In my server.js I've included body parser and made sure the route is after incorporating body parser. So at this point I'm not sure why it would be undefined any help is appreciated.
Here is the post for the blog:
createAuthenticationHeaders() {
this.authService.loadToken();
this.httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/x-www-form-urlencoded',
authorization: this.authService.authToken
})
};
}
newBlog(blog) {
this.createAuthenticationHeaders(); // Create headers
return this.http.post(this.domain + 'blogs/newBlog', blog,
this.httpOptions);
}
This is the payload
Thanks
Here is that file
const express = require('express');
const app = express();
const router = express.Router();
const mongoose = require('mongoose');
const config = require('./config/database');
const path = require('path');
const authentication = require('./routes/authentication')(router);
const blogs = require('./routes/blogs')(router);
const bodyParser = require('body-parser');
const cors = require('cors');
const port = 8080;
mongoose.connect(config.uri, err => {
if (err) {
console.log('Connection error db ', err);
} else {
console.log('Connected to db ', config.db);
}
});
app.use(
cors({
origin: 'http://localhost:4200'
})
);
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/client/dist/'));
app.use('/authentication', authentication);
app.use('/blogs', blogs);
app.get('*', (req, res) => res.sendFile(__dirname +
'/client/dist/index.html'));
app.listen(port, () => console.log(`App listening on port ${port}`));
When I do a console log of the req.body it looks like this:
{ '{"title":"some title", "body":"some body", "createdBy":" "created By"}':''}
You're posting a JSON, which has another JSON as property, therefore req.body.title is undefined. Check your client side, because you're posting the JSON wrong.
// This is what you say you're getting
const bad = { '{"title":"some title", "body":"some body", "createdBy":" "created By"}':''};
console.log(bad);
console.log(bad.title);
// This is what you should post
const good = {"title":"some title", "body":"some body", "createdBy":"created By"};
console.log(good);
console.log(good.title);
Update
You're sending form data, instead of a JSON payload.
use: 'Content-Type': 'application/json' instead of 'Content-Type': 'application/x-www-form-urlencoded'