Axios POST to server returns empty string - javascript

I have a ReactJS form, in which you can enter a new username, which is sent to the server via axios POST and finally saved to a database.
When I click "add" (and thus submit the form), however, it does not save the username I typed into the form input, but returns an empty string.
This is the code for the form including the submit-function:
addUser (e) {
var data = {
entry: this.state.currentname
};
axios.post('users/newuser',
data, {
headers: {"Content-Type": "application/x-www-form-urlencoded"}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
render() {
return (
<div className="App">
<form onSubmit={this.addUser} encType="multipart/form-data">
<label>New username:</label>
<input name="username" value={this.state.currentname} onChange={this.handleChange}></input>
<button type="submit" >Add</button>
</form>
<h1>Current Users: </h1>
<ul>
{this.state.users.map((name, n) =>
<li key={"user_"+n}>{name.username}</li>
)}
</ul>
</div>
);
}
users is the file which contains my curd functions. Here is how I'm currently adding data to the database:
router.route('/newuser')
.post(function (req,res) {
var newUser = new Todo();
newUser.username = req.body.entry;
newUser.save(function (err) {
if(err)
res.send(err);
res.send('User added successfully!');
});
})
Unfortunately, I'm not exactly sure what is going wrong, but I assume that I'm not requesting the username correctly in users.js, since it does insert new data into my database, without a username though.
This is my folder structure (don't know if it's relevant):
-client
public
-index.html
src
-App.js(contains the form)
-server.js
-routes
-users.js
What am I doing wrong exactly and how can I fix that?

So I'm not sure if this is the best way to solve it or if there are better ways (I won't mark my own answer as correct answer since I don't know how correct it is).
What I did was the following:
I added a query parameter to the string in my axios.post request and called for that parameter value in node.js in the function where I insert new data.
These are the parts, which I changed:
App.js:
axios.post('users/newuser?username='+data.entry,
data, {
headers: {"Content-Type": "application/x-www-form-urlencoded"}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
user.js:
router.route('/newuser')
.post(function (req,res) {
var newUser = new Todo();
newUser.username = req.body.username;
newUser.save(function (err) {
if(err)
res.send(err);
res.send('User added successfully!');
});
})

Related

How to show username using HTML and nodejs?

So, I am building a simple login page and I wanna show the username after you succesfully login to the page. But I am kind of confused how to do that in HTML. I saw lots of materials on ejs and angular and react and passport. But I am not using that. I am just using simple HTML,CSS and NodeJS to build this.
So, if someone can help me regarding this, I will be much obliged.
So my HTML page after I login:
<!DOCTYPE html>
<head>
</head>
<body>
Hi user. //want to show the username here
<form name="logout" method="post" action='/logout'>
<label class="logoutLblPos">
<input name="submit2" type="submit" id="submit2" value="log out">
</label>
</form>
</body>
and my code for successful login in server.js file:
app.post("/login", urlencodedParser, async (req, res) => {
const { email, password } = req.body;
db.query(
"SELECT * FROM users WHERE email = ?",
[email],
async (error, result) => {
if (error) {
console.log(error);
} else {
try {
if (result.length === 0 || !result) {
res.json({ message: "Email has not been registered" });
} else {
bcrypt.compare(password, result[0].PASSWORD, (err, results) => {
if (err) {
console.log(err);
return res.json({
message: "there has been some problem matching the password",
});
} else {
if (results) {
//token creation
const id = result[0].ID;
console.log(id)
const token = jwt.sign({ id }, process.env.JWT_SECRET, {
expiresIn: process.env.JWT_EXPIRES_IN,
});
console.log("the token is " + token);
const cookieOptions = {
expires: new Date(
Date.now() +
process.env.JWT_COOKIE_EXPIRES * 24 * 60 * 60 * 1000
),
httpOnly: true,
};
res.cookie("myCookieJwt", token, cookieOptions)
res.status(200).redirect("/user");
} else {
res.json({ message: "Please enter correct password" });
}
}
});
}
} catch (error) {
console.log(error);
return;
}
}
}
);
});
You need to use some kind of library that make POST request to the endpoint. JQuery Ajax to rescue, you can use other libraries like Axios as well
$.ajax({
type: 'POST',
url: "/login",
data: "FORM DATA",//<---- Form Data (username,password)
dataType: "text or JSON", //<-- Whichever you are using
success: function(resultData) { $('#username').text(resultData.username); } //<-- I'm assuming username is coming in
});
you need to return username from node.js endpoint then You can set the text of div or any other HTML tag dynamically.
This example might need a tweaking as it might not work out of the box, but it will set you on correct path.

Calling a mysql column using template literals node js

I am trying to call a field from mysql within my node js file using template literals but am unable to obtain the value. Please take a look at my post.controller.js file below where is says message: Post ${body.post_id} was successfully created where post_id is a field within my mysql database.
//The following code is in post.service.js file
const pool = require("../../config/database");
module.exports = {
//Create new post
createPost: (data, callBack) =>{
pool.query(
`insert into posts(userhandle, post_body)
values(?,?)`,
[
data.userhandle,
data.post_body
],
(error, results, fields) =>{
if(error){
return callBack(error);
}
return callBack(null, results);
}
);
}
}
//The following code is in post.controller.js file
const {
createPost,
} = require("./post.service");
module.exports = {
//Controller for creating new post
createPost: (req, res) =>{
const body = req.body;
createPost(body, (err, results) => {
if(err){
console.log(err);
return res.status(500).json({
success:0,
message:"Error. Unable to create post"
});
}
return res.status(200).json({
success: 1,
message: `Post ${body.post_id} was successfully created`,
data: results
});
});
}
}
I'm guessing post_id is a PK auto incremented, if that so try results.post_id, since this is an object retuned from callback.
If this won't work do the console.log(results) and see if post_id is in it.

ReferenceError: email is not defined

Hi Please help a struggling dev.
I have been trying all day to get this fixed to no avail. Essentially all I want to to do is post from my AddUsers class and for this to be stored through to my sql database. It is a very simple query but has gotten the better off me!The state is updated on change but seems to be an issue with the server.js (error included at bottom of post)
Server.js
app.post("/admin-Add-Users", function(req, res) {
var request = new sql.Request();
// query to the database and get the records
request.query(
"insert into Login (email, password) values ('" +
req.body.email +
"','" +
req.body.password +
"')",
function(err, recordset) {
if (err) console.log(err);
}
);
res.send({ message: "Success" });
});
AddUsers class
class AddUsers extends React.Component {
constructor() {
super();
this.state = { users: [], email: "", password: "" };
this.onSubmit = this.handleSubmit.bind(this);
}
handleSubmit(e) {
e.preventDefault();
const data = { email: this.state.email, password: this.state.password };
fetch("/admin-Add-Users", {
method: "POST", // or 'PUT'
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(data => {
console.log("Success:", data);
})
.catch(error => {
console.error("Error:", error);
});
}
render() {
console.log(this.state.users);
return (
<div>
<LoginForm></LoginForm>
<form>
<input
type="text"
placeholder="email"
value={this.state.email}
onChange={e => this.setState({ email: e.target.value })}
/>
<input
type="text"
placeholder="password"
value={this.state.password}
onChange={e => this.setState({ password: e.target.value })}
/>
<input type="submit" onClick={this.onSubmit} />
</form>
</div>
);
}
}
ReferenceError: email is not defined
UPDATE: After trying recommendations I have been given I now revive a new error.
Error: SyntaxError: Unexpected token < in JSON at position 0
It seems like there is nothing wrong in your React app.
The problem is at your API end where you're formulating an insert query without actually reading the request json content (email & password) fields.
You could add following lines before the query is being generated.
// create sql obj
...
var email = req.body.email;
var password = req.body.password;
...
// your query
You need to add middleware to your express app to be able to parse request body's.
Try adding this to the file where you configure express:
app.use(express.json());
email and password fields must be retrieved from req
This is not a complete answer but it turns out the issue is related to CORS. I am not sure of the solution at this point ,but I am fairly sure this is the cause.
Thanks for all your help :)
Hi Everyone thanks for all your help. I fixed this issue by using the following code within my server.js
app.post("/admin-Add-Users", async (req, response) => {
sql.connect(config, function(err) {
if (err) {
console.log(err);
response.status(400);
response.send(err);
} else {
try {
// create Request object
var request = new sql.Request();
var body = req.body;
console.log(body);
if (body) {
var email = body.email;
var password = body.password;
var queryString = `insert into Login (email,password) values ('${email}', '${password}')`;
console.log(queryString);
request.query(queryString, function(err, recordset) {
console.log(err);
response.status(400);
// response.send(err);
});
response.status(201);
response.send("User added ");
} else {
response.status(400);
response.send("no content was provided");
}
} catch (e) {
console.log(e);
response.status(400);
response.send(e);
}
}
});
});

res.json not returning response

My res.json in my first block of code works, but in the else part of my if statement, it does not. The block that doesnt work, checks for a record in a database then im trying to return the response but im not receiving it.
I've checked and the response is a string, I thought it would have worked as the top part of the code successfully returns the string and it shows in dialogflow (where im trying to return it)
The response is successfully consoled right before the res.json but I do not receive it from the source of the request.
code:
app.post('/webhook/orderinfo', (req, res) => {
const intent = req.body.queryResult.intent.displayName;
const domain = "chatbotdemo.myshopify.com";
const order = req.body.queryResult.parameters["number-sequence"];
if (intent.includes('Order Number')) {
url = "https://test-hchat.com/api/orders/" + domain + "/" + order;
request(url)
.then(function (response) {
order_res = JSON.parse(response)
order_res["fullfillmentText"] = "Hi, Please find your order details below:";
res.json({
"fulfillmentText": JSON.stringify(order_res)
})
})
.catch(function (err) {
console.log(err)
});
// THIS PART DOESNT RETURN THE RESPONSE.
} else {
const domain = 'testStore'
db.getClientsDialog(domain, intent, (response) => {
const fullResponse = response.response
res.json({
fullResponse
})
})
}
});
The database code:
getClientsDialog: function (domain, intent, callback) {
MongoClient.connect('mongodb://efwefewf#wefwef.mlab.com:15799/wefwef', function (err, client) {
if (err) throw err;
var db = client.db('asdsad');
db.collection('dialog').findOne({ domain: domain, intent: intent }, function (err, doc) {
if (!err) {
callback(doc)
} else {
throw err;
callback(err)
}
client.close();
});
console.dir("Called findOne");
});
}
Could it be because this second use of the res.json in the else statement, is trying to call the db first and therefore the link is lost to send the data back?

Sending empty {} after form "post" with pug in node.js

I'm trying to pass form data from login page to signin page via post using fetch with this pug code:
form(id="form-login")
input(type="text", name="email", value="", placeholder="Tu email")
br
input(type="password", name="password", value="", placeholder="Tu contraseña")
br
input(type="submit" value="Conectar")
script.
const formLogin = document.querySelector('#form-login');
const formData = new FormData(formLogin);
formLogin.addEventListener('submit', function(event) {
console.log('Form Data: ', formData);
event.preventDefault();
fetch('/signin', {
method: 'POST',
body: formData
})
.then(function(res) {
res.json();
})
.then(function(data) {
console.log(data)
localStorage.setItem('token', data.token)
})
});
The problem is an empty req.body reaching to signin.. After trace it gives this console.log
Form Data: FormData {}
and also an undefined req.body.
If I comment this script and just send it through form adding action="/signin" and method="post", it works and the answer is printed, but calling storage.setItem({ token: <token> }) returns an Uncaught (in promise) TypeError: Cannot read property 'token' of undefined
I'm wondering why this script is not sending the data... can't figure out... so any help will be much apreciated.
Signin function:
function signIn (req, res) {
if (!req.body.email) return res.status(200).send({message: 'No recibo el usuario'})
User.findOne({ email: req.body.email }, (err, user) => {
if(err) return res.status(500).send({ message: err })
if(!user) return res.status(404).render('login', { title: 'Intenta loguearte de nuevo' })
user.comparePassword(req.body.password, (error, isMatch) => {
if (error) return res.status(500).send({ message: error })
if (!isMatch) {
return res.redirect('login')
} else {
req.user = user
res.status(200).send({
message: 'Te has logueado correctamente',
token: service.createToken(user)
})
//$window.localStorage.setItem({token: service.createToken(user)}); // NO WORKS
return res.body = service.createToken(user) // TRYING THIS WITHOUT KNOWLEDGE ABOUT WHAT AM I DOING :O
}
})
})
}
Thanks in advance.
****EDIT****
As #MichałSałaciński suggest, commenting first .then res.json().... At least gives a response, but still don't undestand what's hapenning here and in order to learn properly and make things better, also hope someone can explain how to correctly do stuff like this.
Response: body : ReadableStream
locked : false
__proto__ : Object
bodyUsed : false
headers : Headers
__proto__ : Headers
ok : true
redirected : false
status : 200
statusText: "OK"
type : "basic"
So I was having the same issue where the POST request from my pug form was sending back an empty {} as the req.body object. The code was a simple create action using these:
bookController.js
exports.createBookForm = (req,res) => {
res.render("create_book_form", { title: "Add A New Book"})
}
exports.createBook = (req,res) => {
const reqFields = ["title", "author"];
for (let i = 0; i < reqFields.length; i++) {
const field = reqFields[i];
if (!field in req.body) {
const message = `Missing ${field} in the request body`;
console.log(message)
return res.status(400).send(message)
}
}
Book
.create({
title: req.body.title,
author: req.body.author,
summary: req.body.summary
})
.then((book) => {
res.status(201).json(book.serialize())
})
.catch(err => {
console.log(err);
})
}
And the create book form:
block content
h1 Add a Book
h3 Do use real details. Otherwise, what's the point?
form(method="POST" action="/books")
div.form-group
label(for="title") Title:
input#title.form-control(type="text", placeholder="Small Gods" name="title")
label(for="author") Author:
input#author.form-control(type="text", placeholder="Terry Pratchett" name="author")
label(for="summary") Summary:
textarea#summary.form-control(type="text", placeholder="God is turtle, world is flat" name="summary")
div.form-group
button.btn.btn-primary(type="submit" role="submit") Add Book
What finally fixed getting the actual req.body to show up for the POST action was adding (within server.js)
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
Let me know if this works for you. Took me a couple hours to come to this conclusion and I hate seeing questions go unanswered.
You should move "new FormData" inside "send" event listener. Also, there's missing comma after type="submit", but overall, the problem got nothing to do with pug :)
form(id="form-login")
input(type="text", name="email", value="", placeholder="Tu email")
br
input(type="password", name="password", value="", placeholder="Tu contraseña")
br
input(type="submit",value="Conectar")
script.
const formLogin = document.querySelector('#form-login');
formLogin.addEventListener('submit', function(event) {
const formData = new FormData(formLogin);
console.log('Form Data: ', formData);
event.preventDefault();
fetch('/signin', {
method: 'POST',
body: formData
})
.then(function(res) {
res.json();
})
.then(function(data) {
console.log(data)
localStorage.setItem('token', data.token)
})
});

Categories