Angular 5 Post data with Nodejs - Wrong format of body - javascript

I am using nodejs as back-end for angular 5 application . When I am posting data with http post request then it coming at nodejs in wrong formate (Values as property)-
This is my service code of angular 5 -
login(email: string, password: string) {
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
let body = { EmailAddress: email, Password: password };
return this.http.post('http://localhost:3000/api/user/login', body, options )
.map((response: Response) => {
let user = response.json();
if (user && user.token) {
localStorage.setItem('currentUser', JSON.stringify(user));
}
});
}
This is Node API - in body I am getting value as property
app.post('/api/user/login', urlencodedBodyparser, function (req, res) {
console.log(req.body);
User.find({ "EmailAddress": req.body["EmailAddress"], "Password": req.body["Password"] }, function (err, users) {
console.log(users.length);
if (err != null) {
sendError(err, res);
}
if (users != null) {
var count = users.length;
if (count > 0) {
response.data = users[0];
res.json(response);
}
else {
sendError({ message :'No user found'}, res);
console.log("Login Failed");
}
}
else {
sendError(err, res);
}
})
});
Code for body parser -
var bodyParser = require('body-parser');
var urlencodedBodyparser = bodyParser.urlencoded({ extended: false });
app.use(urlencodedBodyparser);

try to change the header content-type to json
application/json
like this:
options() {
const headers = new Headers({
'content-type': 'application/json'
});
const options = new RequestOptions({ headers: headers });
return options;
}
login(): Observable<any> {
return this.http.post('http://localhost:3000/api/user/login', this.options()).
map((res: Response) => res.json());
}

You need to use body-parser middleware https://github.com/expressjs/body-parser
Here is more information What does body-parser do with express?
Try to use this :
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));

Related

Compose the correct FormData request

By sending a request to the server through the postman everything works:
When trying to send the same request through the client, the req.body on the server is equal to an empty object:
const img = ev.target.files[0];
const body = new FormData();
body.append('image', img);
body.append('user', localStorage.getItem('user'));
const data = await (await fetch(`${root}/api/upload/profile`, {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data;'
},
body
})).json();
/profile route:
router.post('/profile',
cors(corsOptions),
async(req, res) => {
upload(req, res, async err => {
try {
console.log(req.body) // {}
} catch (err) {
console.log(err.stack)
}
});
}
);

Express js request body is not excatcly i want

Im working on simple app that allows you to register new user. I managed to create fetch POST request and catch it with express app.post method. It works but the value that req.body is retruning is not plain object but something more that I want.
It's literally returning something like this : { '{"login":"fff","password":"sss"}': '' }
But I want it to be just sth like this: {"login":"fff","password":"sss"}
Here is my client side code
function eventListener() {
const formSubmit = document.querySelector('.register-form');
const newUser = new Register();
formSubmit.addEventListener('submit', (e) => {
e.preventDefault();
newUser.checkInputs();
const form = e.target;
const formData = new FormData(form)
const userData = {
login: formData.get('login'),
password: formData.get('password'),
}
console.log(userData);
fetch('/register', {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
body: JSON.stringify(userData)
})
.then(response => {
console.log(response);
})
})
}
document.addEventListener('DOMContentLoaded', eventListener)
And here is server code
const express = require('express');
const path = require('path');
const app = express();
app.use(express.json())
app.use(express.urlencoded({
extended: true
}))
app.use(express.static('static'))
app.post('/register', (req, res) => {
console.log('ok');
console.log(req.body);
res.end();
})
app.listen(process.env.PORT || 5000, () => {
console.log('running...');
})
Don't lie to the server:
'Content-Type': 'application/x-www-form-urlencoded'
You are sending JSON.
By telling the server you are NOT sending JSON, you are confusing it.
It is trying to parse it as application/x-www-form-urlencoded
Tell it you are sending JSON:
'Content-Type': 'application/json'

POST method returns empty object in both client and server

So I am building a recipe search engine and I want to transfer the user's choice of the category to the server so I can use it in API call. Here's some code :
CLIENT-SIDE
function getRecipes(category){
const categorySearch = category.alt;
let data = {
categoryChoice: categorySearch
}
console.log(data);
let options = {
method: 'POST',
headers: {
'Content-type': 'text/plain'
},
body: JSON.stringify(data)
}
const promise = fetch('/data', options);
console.log(promise);
}
SERVER-SIDE
const express = require('express');
const app = express();
const fetch = require('node-fetch');
require('dotenv').config();
const API_KEY = process.env.API_KEY;
const port = process.env.PORT || 3000;
app.listen(port, () => console.log('listening at 3000'));
app.use(express.static('public'));
app.use(express.json({ limit: "1mb"}));
app.post('/data', (request, response) => {
let data = request.body;
console.log(data);
response = "Got data";
console.log(response);
})
categorySearch and data variables definitely get what it should, I have logged in and it's working fine. Then whether I log promise in client-side or data in server-side I only get {}, any ideas?
Working with JSON content type.
Backend-Side should be returning data:
app.post('/data', (request, response) => {
let data = request.body;
let gotData;
if(data.categoryChoice == "option1")
gotData = {id:1, label:"val 1", q:data.categoryChoice};
else
gotData = {id:2, label:"val 123", q:data.categoryChoice};
response.json(gotData);
});
And the Client-Side:
let data = { categoryChoice: "option1" };
let options = {
method: 'POST',
headers: {
"Content-type": "application/json; charset=UTF-8"
},
body: JSON.stringify(data)
}
const promise = fetch('/data', options);
promise.then(response => {
if (!response.ok) {
console.error(response);
} else {
return response.json();
}
}).then(result => {
console.log(result);
});
Your backend part should be returning a response for it to work the way you expect it.
You are only handling a POST request but you also need a get request.
app.get('/data', (request,response) => {
return response.json({
// JSON data here
})
})

React, axios, content-type

I have already searched a lot, but none of the solutions found work: Cannot send content-type by axios. but if I use the postman interceptor and I 'send' the request generated by axios this time it works: the node.js / express server correctly receives the request and body-parser works normally!
React side:
const API_URL = "http://localhost:8800/auth/";
const headers = {
accept: 'application/json, text/plain, */*',
'content-type': 'application/json;charset=UTF-8'
};
class AuthService {
register(pseudo, email, password) {
return axios.post(API_URL + "signup/",
{ pseudo, email, password },
{ headers: headers})
.then(response => {
if (response.data.accessToken) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
});
}
server side
const app = express();
app.use(function (req, res, next) {
console.log( req.headers);
next();
});
app.use( bodyParser.urlencoded({ extended: true }), bodyParser.json());
Usually when I use axios I send the headers in a config variable like this and I stringify the body so it sends as JSON object and not a JS object.
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({arguments});
try {
const res = await axios.post(/url, body, config);
...
Here's a link to the docs for a little more reading about it:
https://github.com/axios/axios

Post request with node js

I'm trying to make a post request with node.js and when I try to run it, I get the data to show up in the console but noot the body of my HTML. In the console I get the error
app.js:4 POST http://localhost:8000/addAnimal net::ERR_EMPTY_RESPONSE
postData # app.js:4
(anonymous) # app.js:25
app.js:21 Uncaught (in promise) TypeError: Failed to fetch
It seems like the function is working but not the actual post request part. I can't for the life of me figure out what I'm doing wrong.
This is my code:
server.js:
projectData = {};
/* Express to run server and routes */
const express = require('express');
/* Start up an instance of app */
const app = express();
/* Dependencies */
const bodyParser = require('body-parser')
/* Middleware*/
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
const cors = require('cors');
app.use(cors());
/* Initialize the main project folder*/
app.use(express.static('project1'));
const port = 8000;
/* Spin up the server*/
const server = app.listen(port, listening);
function listening(){
// console.log(server);
console.log(`running on localhost: ${port}`);
};
// GET route
app.get('/all', sendData);
function sendData (request, response) {
response.send(projectData);
};
// POST route
app.post('/add', callBack);
function callBack(req,res){
res.send('POST received');
}
// POST an animal
const data = [];
// TODO-Call Function
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body)
})
app.js
/* Function to POST data */
const postData = async ( url = '', data = {})=>{
console.log(data);
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
const newData = await response.json()
// console.log(newData);
return newData.json()
}catch(error) {
console.log("error", error)
// appropriately handle the error
};
};
// TODO-Call Function
postData('/addAnimal', {animal:'lion'});
Any help would be greatly appreciated.
Thanks,
Mike
💡 The only one reason why you got message like it, it's because you never send response to the client.
👨‍🏫 So, You should to send response to the client. For an example, you can look at this code below: 👇
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
// send data to client
// you can change req.body with the object what you want to sent do the client
res.status(200).send(req.body);
})
📤 Update: Addtional information
Make sure you call the endpoint: http://localhost:8000/addAnimal.
Frontend: Make sure your code like this code below
const postData = async ( url = '', data = {})=>{
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data), // body data type must match "Content-Type" header
});
try {
console.log(await response.json());
return await response.json()
}catch(error) {
console.log("error", error);
};
};
I hope it can help you 🙏.
Try this:
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
res.send('done'); // send response
});
Change the app.js code with the below.
/* Function to POST data */
const postData = async (url = "", data = {}) => {
const response = await fetch(url, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
try {
return response.json();
} catch (error) {
console.log("error", error);
// appropriately handle the error
}
};
// TODO-Call Function
(async function(){
let res = await postData("/addAnimal", { animal: "lion" });
console.log(res);
})();
And also change the post method like below.
app.route('/addAnimal')
.get(function (req, res) {
res.sendFile('index.html', {root: 'project1'})
})
.post(function (req, res) {
data.push(req.body);
res.status(200).send(data);
})

Categories

Resources