I'm working on a web app and I'm sending a post request with ajax to a node+express backend. The problem is that in the backend the values for all parameters are NULL, I have checked by console.log(data) on the front end before sending ajax request and I'm getting the values here but on the backend request.query has all params with NULL values.
AJAX Request
const data = {
first_name: fn,
last_name: ln,
email: email,
password: password,
job_title: job,
security: security,
mobile: mobile,
remarks: remarks,
};
console.log("Data : ");
console.log(data);
$.post(
"http://127.0.0.1:4000/user/add",
data,
function (response) {
console.log(response);
}
);
Console Log For Data
Data :
{first_name: 'a', last_name: 'a', email: 'admin#gmail.com', password: '13011301', job_title: 'CV-Specialist', …}
Backend Code
app.post("/user/add", (req, res) => {
const data = req.query;
var sql =
"Insert into users (first_name,last_name,email,password,job,security,mobile,remarks) values (?,?,?,?,?,?,?,?)";
conn.query(
sql,
[
data.first_name,
data.last_name,
data.email,
data.password,
data.job,
data.security,
data.mobile,
data.remarks,
],
function (err, result) {
if (err) {
res.send(err);
} else {
res.send("1 record inserted");
}
}
);
});
Backend Response
{code: 'ER_BAD_NULL_ERROR', errno: 1048, sqlMessage: "Column 'first_name' cannot be null", sqlState: '23000', index: 0, …}
code
:
"ER_BAD_NULL_ERROR"
errno
:
1048
index
:
0
sql
:
"Insert into users (first_name,last_name,email,password,job,security,mobile,remarks) values (NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL)"
sqlMessage
:
"Column 'first_name' cannot be null"
I have searched for solutions and explanations but I can't figure out what's causing this. Any help or hints will be appreciated, thank!
The default content type header of jquery for Ajax is application/x-www-form-urlencoded. You are expected to send data in the query Params like so:
$.ajax({
url: 'http://www.example.com?' + $.param({first_name: 'a', last_name: 'a', email: 'admin#gmail.com', password: '13011301', job_title: 'CV-Specialist', …}),
method: 'POST'
});
Either send all of your data encoded in query params as shown above
or
set headers to application/json
$.ajax({
url: 'YourRestEndPoint',
headers: {
'Content-Type':'application/json'
},
method: 'POST',
data: data,
success: function(data){
console.log('succes: '+data);
}
});
on the server side ensure you have body parser configured:
const bodyParser = require('body-parser');
.
.
.
.
.
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
In your middleware callback get data in req.body instead of req.query :
app.post("/user/add", (req, res) => {
const data = req.body;
var sql =
"Insert into users (first_name,last_name,email,password,job,security,mobile,remarks) values (?,?,?,?,?,?,?,?)";
conn.query(
sql,
[
data.first_name,
data.last_name,
data.email,
data.password,
data.job,
data.security,
data.mobile,
data.remarks,
],
function (err, result) {
if (err) {
res.send(err);
} else {
res.send("1 record inserted");
}
}
);
});
Related
Task
Parse a CSV file
Send the data to an API enpoint
Save data to MySql database
Problem
The request body is showing up empty when I send data via fetch. However, I can send and see the body data if I use Postman.
I've added a console.log(req.body) and it's printing out {} to the console.
Parse and Send Data to Endpoint
const changeHandler = (event) => {
Papa.parse(event.target.files[0], {
header: true,
skipEmptyLines: true,
complete: function (results) {
results.data.forEach(entry => {
// Create the data object.
let data = {};
let keys = ['Date', 'Description', 'Debit Amount'];
for (let key in entry) {
if (keys.includes(key)) {
data[key.toLowerCase().replaceAll(' ', '_')] = entry[key];
}
}
// Send data to server
fetch('http://localhost:3001/api/create_transactions', {
method: 'POST',
mode: 'no-cors',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data),
}).then(function (response) {
console.log(response);
})
});
},
});
// Reset file input
event.target.value = null;
};
Save Data to MySql
app.use(express.json());
const crypto = require('crypto');
app.post("/api/create_transactions", (req, res) => {
console.log(req.body);
/*
let hash = crypto.createHash('md5').update(req.body['date'] + req.body['description'] + req.body['debit_amount']).digest('hex');
let data = [
hash,
req.body['date'],
req.body['description'],
req.body['debit_amount'],
];
db.query('insert into transactions (`hash`, `date`, `description`, `debit_amount`) values (?, ?, ?, ?)', data, (err, result, fields) => {
if (err) {
console.log(err);
} else {
console.log(result);
res.send(JSON.stringify({"status": 200, "error": null, "response": result}))
}
});
*/
});
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`);
});
According to this post Fetch: post json data, application/json change to text/plain you can not change the Content-Type to application/json if you are using no-cors. So I will have to enable cors if I want to use fetch.
Using this tutorial https://www.section.io/engineering-education/how-to-use-cors-in-nodejs-with-express/ I was able to enable cors on my nodejs server and receive the proper headers.
Try to use express's bodyParser app.use(express.bodyParser());
this is my login post method in the reactjs frontend
const login = () => {
Axios.post("http://localhost:3001/api/users/login", {
email: values.email,
password: values.password,
}).then((response) => {
console.log(response.data);
}).catch(err =>{
console.log(err)
})
};
this is my expressjs server side, here i have login post method for reactjs frontend, where iam on response i want to send token to set in cookie whenever user post on login method, below is code for login post method
login: (req, res) => {
const body = req.body;
console.log("req.body :", req.body);
getUserByEmail(body.email, (err, results) => {
console.log("results :", results);
if (err) {
console.log(err);
return;
}
if (!results) {
res.json({
status: "failure",
msg: "Invalid email or password",
});
}
const result = compareSync(body.password, results.password);
const SECRET_KEY = "xyz123";
if (result) {
results.password = undefined;
const jsontoken = sign({ result: results }, SECRET_KEY, {
expiresIn: "1h",
});
// console.log(res)
res.cookie("token", jsontoken, {
httpOnly: true,
domain: "http://localhost:3000/login",
});
return res.json({
status: "Success",
msg: "login Successfully",
token: jsontoken,
});
} else {
return res.json({
status: "failure",
msg: "Invalid email or password",
});
}
});
},
What you could do, that is actually more secure, is tell the browser using headers on the response to create a cookie.
There is a header in HTTP called Set-Cookie, which is responsible to do just that, you can read more about it here: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie.
The way you add it to your request on express is by calling the res.cookie function on your express request handler. I would suggest telling the cookie to be httpOnly in order for it to not be accessible through JS code, this is just a way to avoid XSS attacks.
Here you have an example to how to achieve that:
res.cookie('token', jsontoken, { httpOnly: true });
Then in order to access the cookie, you would need to use the cookieParser middleware which is responsible in putting all the cookies the client sent in req.cookies.
You use it this way:
app.use(express.cookieParser());
I am using nodejs and express to connect my local mysql db, everythings look working well except no response when Iam trying to test the API in postman.
here is my code in server.js
//add sales
app.post('/sales',(req, res) => {
var POST_SALES_QUERY = {
username: req.body.username,
password: req.body.password,
fullname: req.body.fullname
}
if (!POST_SALES_QUERY) {
return res.status(400).send({ err: true, message: 'Please username' });
}
dbConn.query("INSERT INTO user_tbl SET ?", (POST_SALES_QUERY, err, results) => {
if(err){
console.log(err);
} else {
return res.send(JSON.stringify({"status": 200, "err" : null, "response": results}));
}
});
});
and in Postman, I get this:
any idea what the problem appears here?
app.post('/sales',(req, res) => {
var POST_SALES_QUERY = {
username: req.body.username,
password: req.body.password,
fullname: req.body.fullname
}
if (!POST_SALES_QUERY) {
return res.status(400).send({ err: true, message: 'Please username' });
}
let query = `INSERT INTO user_tbl (username, password, fullname) VALUES ('${POST_SALES_QUERY.username}','${POST_SALES_QUERY.password}','${POST_SALES_QUERY.fullname}')`;
dbConn.query(query,function(err,results) {
if(err){
console.log(err);
} else {
return res.status(200).json({"status": 200,"err": null,"response": results});
}
});
});
You need to tell express to treat the body as json, by calling the following codes:
app.use(express.json())
As per the documentation:
This is a built-in middleware function in Express. It parses incoming requests with JSON payloads and is based on body-parser.
I want to make an HTTP POST request to a server with credentials (username, password) and content.
More specifically, I used various approaches without success. One of them is:
var request = require('request');
request({
url: 'https://path',
method: 'POST',
auth: {
user: 'username',
pass: 'password'
},
form: {
'grant_type': 'client_credentials',
'text' : 'input-text',
'features': {
'score': true,
}
}
}, function(err, res) {
console.log(res);
var json = JSON.parse(res.body);
console.log("Access Token:", json.access_token);
});
Do you have any suggestion?
I feel more comfortable using promises. request-promise documentation
var request = require('request-promise');
var options = {
method: 'POST',
url: '',
auth: {
user: '',
password: ''
},
headers: {
'': ''
},
json: true
}
return request(options)
.then(function (response) {
// manipulate response
}).catch(function (err) {
return err
})
I'm developing a MEAN stack application and I'm hung up on how to actually update a document that has been saved into the MongoDB already. I've seen that I have to use patch instead of post in my REST API paths, but it's still a little clouded to me. I want to insert a new Package into the Package JSON Array in the User JSON.
Possible Duplicate, but he's overriding a value in the array and not adding a new object into it.
My JSON Schema:
//User schema
const UserSchema = mongoose.Schema({
name: {
type: String
},
email: {
type: String,
require: true
},
username:{
type:String,
required: true
},
password:{
type:String,
required: true
},
packages: [{
from: String,
to: String,
tracking: String
}]
});
My REST API Paths
//Update
router.patch('/update', (req, res) => {
const username = req.body.username;
const packages = req.body.packages;
User.getUserByUsername(username, (err, user) => {
if(!user){
return res.json({success: false, msg: 'User not found'});
} else {
User.addPackages(user, req.body.packages, (err, user) => {
if(err){
res.json({success: false, msg:'Failed to update packages'});
} else {
res.json({success: true, msg:'update packages'});
}
})
}
});
});
My Module's:
module.exports.addPackages = function(user, packages, callback){
User.findOneAndUpdate(
{username:user.username},
{$push: {"packages" : {
"to" : packages.to,
"from" : packages.from,
"tracking" : packages.tracking
}}},
{new:true},
function(err, newPackage){
if (err) throw err;
});
}
module.exports.getUserById = function(id, callback){
User.findById(id, callback);
}
module.exports.getUserByUsername = function(username, callback){
const query = {username: username}
User.findOne(query, callback);
}
They're updating into my MongoDB, but just the object ID and not the values...
db.your_collection.update({},
{$set : {"new_field":1}},
{upsert:false,
multi:true})