I got following format when i send post request from postman.
{
ID:"66",
Blod:"test",
Allergic:"no",
Chronic:"no"
}
But i got this format when i send post request using react app post method.
[Object: null prototype]
{
'{
"ID":"123456789",
"Blod":"22334445",
"Allergic":"6677788",
"Chronic":"3445566"}': ''
}
please help me how can I got the same format of postman to insert data correctly.
this is my method from react app uisng axios module :
submithandler=(e)=>{
e.preventDefault();
axios.post('http://localhost:8000/api/addsickers',
JSON.stringify({
ID:'123456789',
Blod:'22334445',
Allergic:'6677788',
Chronic:'3445566'
}),
)
.then(response=>{
alert(response);
})
.catch(err=>{
alert("catch"+err);
});
}
I use parsing on api
app.use(bodyparser.json());
// parse application/x-www-form-urlencoded
bodyparser.urlencoded({ extended: false });
// parse the raw data
app.use(bodyparser.raw());
// parse text
app.use(bodyparser.text());
Please check the postman request configuration
settings as follows.
If the problem you are facing now is that how to process incoming react request, the
following code snippet will helps you.
router.post('/', (req, res) => {
let request = JSON.parse(JSON.stringify(req.body));
console.log(request.ID);
});
you don't need to use 'JSON.stringify' , like this:
submithandler=(e)=>{
e.preventDefault();
axios.post('http://localhost:8000/api/addsickers',
{
ID:'123456789',
Blod:'22334445',
Allergic:'6677788',
Chronic:'3445566'
},
)
.then(response=>{
alert(response);
})
.catch(err=>{
alert("catch"+err);
});
}
In your code you don't need this code:
// parse the raw data
app.use(bodyparser.raw());
// parse text
app.use(bodyparser.text());
As the documentation states:
bodyparser.raw() Returns middleware that parses all bodies as a Buffer and only looks at requests where the Content-Type header matches the type option.
And
bodyParser.text() Returns middleware that parses all bodies as a string and only looks at requests where the Content-Type header matches the type option. This parser supports automatic inflation of gzip and deflate encodings.
You have to change that line from:
bodyparser.urlencoded({ extended: false });
to:
app.use(bodyparser.urlencoded({ extended: false });
I have solved this by using fetch method like the following :
senddata(event){
event.preventDefault();
//if(!this.formvalidation())
//{
try{
fetch('https://localhost:8000/api/addsickers/',{
method:'post',
mode:'no-cors',
headers:{
'Accept':'application/json',
'Content-type': 'application/json'
},
body:JSON.stringify({
ID:this.state.code,
Blod:this.state.blod,
Allergic:this.state.allergic+" - "+this.state.allergicdescription,
Chronic:this.state.chronic+" - "+this.state.chronic_description
})
});
alert("data goes")
}catch(e){
alert(e)
}
//}
}
and in api I did :
let request = JSON.parse(req.body)
console.log(request);
and I got the same forma of postman tool that let me to call attributes correctly for insert , for example : request.ID return the correct value.
thank you all for your help.
Related
I am using React + NodeJS & Axios but have been trying to send a post request but experiencing difficulties.
The request seems to be posting successfully, but all actions at the nodejs server is returning in the "undefined" data value, even if the data is passed successfully shown in the console.
REACT
const fireAction = (data1, data2) => {
const data = JSON.stringify({data1, data2})
const url = `http://localhost:5000/data/corr/fire`;
const config = {
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'AUTHCODE',
}
}
axios.post(url, data, config)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
fireAction("Oklahoma", "Small apartment")
NODE
app.post('/data/corr/fire', async (req, res) => {
try {
const data = req.body.data1;
console.log(data)
} catch(e) {
res.send({success: "none", error: e.message})
}
});
Result of node: "undefined"
I have added the following body parser:
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
I am not sure why this error is happening. I see there is similar questions to mine: however none of them are applicable as I'm using both express and body parser which is already suggested.
You're POSTing JSON with a content-type meant for forms. There's no need to manually set content-type if you're sending JSON, but if you want to manually override it, you can use 'Content-Type': 'application/json', and access the response in your route with req.body. If it does need to be formencoded, you'll need to build the form:
const params = new URLSearchParams();
params.append('data1', data1);
params.append('data2', data2);
axios.post(url, params, config);
What i want to do is to read the property name of the request i send to my express.js server.Here is how i pass the json data to a post request.
document.querySelector('#checkout').onsubmit= async e =>{
const form = new FormData(document.querySelector('#checkout'))
let user = createUserInfo(form),
order = {
name: "Test_Name"
}
fetch("/checkout/create-order", {
method: "POST",
mode: "same-origin",
redirect: 'manual',
headers:{
"Content-Type": "application/json"
},
body: JSON.stringify(
{
order: order,
user: {
name:"test_Name"
}
}
)
}).then(res=>{
res.ok
}).then(data=>{
console.log(data)
})
}
And this is how i read it using express.js:
app.use(express.json());
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: false }));
const YOUR_DOMAIN = 'http://localhost:4242/checkout.html';
app.post('/checkout/create-order', async (req, res) => {
console.log(req.body.order.name)
}
When i try to read the name property i get an error.
C:\xampp\htdocs\server.js:9
console.log(req.body.order.name)
^
TypeError: Cannot read properties of undefined (reading 'name')
Add e.preventDefault() to the beginning of the onsubmit handler.
By default, when the user clicks a form submit button, the browser will send a URL encoded POST request to the URL defined in the form's action attribute (or if there is no action, the current page).
<form action="/somewhere_else"></form>
Your express code is seeing the request sent from the browser, which doesn't have any of the values you defined in the fetch request.
This also causes the page to reload and interrupt your fetch request code before its sent. By adding event.preventDefault() you suppress this behavior and your code should run as expected.
P.S.
You don't need to use both express.json() and bodyparser.json(). Body-parser is included with Express, so both of those middlewares are doing the same thing. You can also use express.urlencoded() instead of bodyparser.urlencoded().
Your server-side code is correct in my opinion, but a small tip, you don't need to use bodyparser.json() and express.json() both do the same thing.
just chose one and stick to it.
I know that a similar question has been asked many times, e.g. here.
However, I've tried applying various solutions from these answers without success.
Here's my client-side page:
<form id="submit_newuser" method="POST" action="/submit_newuser">
User name:
<input type="text" id="username" name="username" />
<br>
Phone number:
<input type="text" id="phonenumber" name="phonenumber" />
<br><br>
<input type="submit" />
</form>
<script>
document.getElementById("submit_newuser").addEventListener('submit',submit_newuser);
function submit_newuser(event){
event.preventDefault();
submit_newuserForm=document.getElementById("submit_newuser");
formData=new FormData(submit_newuserForm);
fetch("/submit_newuser",{
body:formData,
headers:{
"Content-Type": "application/json"
},
method:"post"
})
.then(response=>console.log(response))
.catch(err=>"submit_newuser: error: "+err);
}
</script>
And here's the relevant server-side code for the /submit_newuser endpoint:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/submit_newuser',function(req,res){
console.log("/submit_newuser: req.body: "+JSON.stringify(req.body));
var phonenumber=req.body.phonenumber;
var username=req.body.username;
var output="you submitted: "+username+" "+phonenumber;
console.log("/submit_newuser: text to send back: "+output);
res.send(output);
});
With this, when I submit data from the page, the server logs this error:
SyntaxError: Unexpected token - in JSON at position 0
When I change the Content-Type to "application/x-www-form-urlencoded", I get this console logging:
/submit_newuser: req.body: {"------WebKitFormBoundaryBDU4OcntAv7d5wWL\r\nContent-Disposition: form-data; name":"\"username\"\r\n\r\ntestUserName\r\n------WebKitFormBoundaryBDU4OcntAv7d5wWL\r\nContent-Disposition: form-data; name=\"phonenumber\"\r\n\r\ntestPhoneNumber\r\n------WebKitFormBoundaryBDU4OcntAv7d5wWL--\r\n"}
/submit_newuser: text to send back: you submitted: undefined undefined
Which indicates that the data is being posted to the server, but not properly parsed into req.body.
Solutions involving multer don't seem to apply here because I'm not uploading a file, but I'm not sure if I should nonetheless be using a different approach than posting a FormData object in the fetch() body.
I'm confused, and also wondering if there's a simpler way to do this. I just want to post form data to the server without triggering a page refresh, and be able to update page elements with the server response.
You can update your client-side code to send a JSON body like so, this will be parsed correctly by the server.
Because we're setting the content-type header to JSON on the client, we must send JSON data. We could send url encoded data or multipart/form-data, however we would have to change headers on the client to do this.
document.getElementById("submit_newuser").addEventListener('submit',submit_newuser);
function formDataToJson(formData) {
const obj = {};
formData.forEach((value, key) => {
obj[key] = value
});
return JSON.stringify(obj);
}
function submit_newuser(event){
event.preventDefault();
submit_newuserForm=document.getElementById("submit_newuser");
formData = new FormData(submit_newuserForm);
fetch("/submit_newuser",{
body: formDataToJson(formData),
headers: {
"Content-Type": "application/json"
},
method:"post"
})
.then(response=>console.log(response))
.catch(err=>"submit_newuser: error: "+err);
}
If you're trying to send client's request as formData then you must handle your backend-side to receive request as formData.
There is a npm module called multer for handling formData request type.
Anyway your code must change to something like this:
Client-side
<script>
document.getElementById("submit_newuser").addEventListener('submit',submit_newuser);
function submit_newuser(event){
event.preventDefault();
submit_newuserForm=document.getElementById("submit_newuser");
formData=new FormData(submit_newuserForm);
fetch("http://127.0.0.1:3000/submit_newuser",{
body:formData,
method:"post"
})
.then(response=>console.log(response))
.catch(err=>"submit_newuser: error: "+err);
}
</script>
Server-side
const multer = require('multer');
const upload = multer();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.post('/submit_newuser', upload.none(), function (req, res) {
console.log("/submit_newuser: req.body: " + JSON.stringify(req.body));
var phonenumber = req.body.phonenumber;
var username = req.body.username;
var output = "you submitted: " + username + " " + phonenumber;
console.log("/submit_newuser: text to send back: " + output);
res.send(output);
});
Use below sample ajax call for sending data from frontend.
var settings = {
"async": true,
"crossDomain": true,
"url": "http://localhost:3000/submit_newuser",
"method": "POST",
"data": {
"username": "test user",
"phonenumber": "03453512545"
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
sample postman request.
I'm trying to get/read the response from a POST request made in Angular 7, if I set the API to return "text" everything is OK, but when i make the response a JSON the response body on Angular is null.
If I try the API on Postman I get full response JSON body.
I tried changing response method on Express API (from the simple res.json() to the "old" way of declaring Content-Type and sending it with res.end()), nothing changed.
The response code I'm using on backend:
res.status(200).json({
success: true,
token: token
})
What I also tried:
res.writeHead(200, { 'Content-Type': 'application/json' })
var json = JSON.stringify({
success: true,
token: token
})
res.end(json)
The service I'm using on Angular:
login(username: string, password: string): Observable<any> {
let body = {username: username, password: password};
let headers = new HttpHeaders();
headers.set('Content-Type', 'application/json');
return this.http.post(this.baseUrl + "/login/sign-in", body, {headers: headers, responseType: 'json', observe: 'response'});
}
The call to that service:
this.api.login("admin", "password").subscribe(result => {
console.log(result);
})
On Postman I get this result:
On Angular I get this (JSON):
On Angular I get this (TEXT):
Edit:
If I add anything before the JSON on the Express app, the body is no more null:
res.writeHead(200, { 'Content-Type': 'application/json' })
var json = JSON.stringify({
success: true,
token: token
})
res.end('some_char' + json)
The result (of course the response goes in error):
Edit 2:
I'm also trying (with no luck) with this simple version of the endpoint:
const express = require('express')
const app = express()
app.post('/login/sign-in', (req, res) => res.json({ value: 1 }))
app.listen(3000, () => {
console.log('App running on port 3000.')
})
Solution:
It was all a CORS problem, I added this to the backend and everything is working fine:
app.use(cors())
Spent a few minutes trying to find out why the body would be empty,
In my case, I had "mode":"no-cors" set in my fetch() options, therefore the returned value from the server would appear as "opaque"
redux fetch body is not use with no cors mode
I hope this can help !
I am trying to POST some variables as part of req.body to a Firebase Cloud Function. I am using the modern fetch() syntax as following:
const { licenseCode } = this.state;
fetch('https://myAPI.com/inputLicense', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({ licenseCode })
})
And here is how my Cloud function looks:
exports.inputLicense = functions.https.onRequest((request, response) => {
// const { licenseCode } = request.body
console.log(request.get('content-type'))
console.log('query', request.query)
console.log('body', request.body)
})
Unfortunately, all of the above logging produces empty objects or undefined in the case of the first line. In a usual Express setup, I know I need to use:
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
But don't know how to do it with cloud functions. Google claims in their Docs they parse my requests automatically, based on the header but I just can't get it to work.
Any help is more then welcome, thanks in advance.
It seems like you solved the problem, but for anyone else having a problem. In my case the problem was the firebase cloud function triggering on the cors preflight request which contains no body.
I solved it by removing the application/json content-type in the fetch call and decoding the json body manually in the cloud function
// on the client
fetch(functionURL + '/' + name, {
body: JSON.stringify({abc: 123}),
method: 'POST',
mode: 'cors',
})
// on the server
functions.https.onRequest(async (req, res) => {
const {abc} = JSON.parse(req.body)
res.set('content-type', 'application/json')
res.set('Access-Control-Allow-Origin', '*')
res.status(200)
res.send({result: abc})
})
I've done some tests and apparently the problem comes from the object destructuring.
The following should work:
const obj = { licenseCode: this.state };
fetch('https://myAPI.com/inputLicense', {
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(obj)
})