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);
}
}
});
});
Related
I want to add some company details to mongo DB, and the details include a company logo. So I want to upload the picture to Cloudinary and then save the URL in Mongo DB with the other details.
But my code doesn't seem to work. When I fill the form and click on submit, the image gets uploaded to Cloudinary but it does not get saved in the Database.
To store the image
const [ companyLogo, setCompanyLogo] = useState("");
const [ companyLogoURL, setCompanyLogoURL] = useState("");
Function to execute on submit
const handleCompanySubmit = (evt) => {
evt.preventDefault();
const data = new FormData()
data.append("file", companyLogo)
data.append("upload_preset", "Sprint")
data.append("cloud_name", "sprint-ccp")
fetch("https://api.cloudinary.com/v1_1/sprint-ccp/image/upload",{
method:"post",
body:data
})
.then(res => res.json())
.then(data => {
setCompanyLogoURL(data.url)
})
.catch(err => {
console.log(err)
})
//check for empty fields
if (
isEmpty(companyName) ||
isEmpty(companyAddress) ||
isEmpty(companyRegNumber) ||
isEmpty(companyContactNumber)
) {
setCompanyErrorMsg("Please Fill All The Fields");
}else {
let formData = new FormData();
formData.append('companyName', companyName);
formData.append('companyAddress', companyAddress);
formData.append('companyRegNumber', companyRegNumber);
formData.append('companyContactNumber', companyContactNumber);
formData.append('companyLogo', companyLogoURL);
setCompanyLoading(true);
addCompany(formData)
.then((response) => {
setCompanyLoading(false);
setCompanySuccessMsg(response.data.successMsg)
setCompanyData({
companyName: "",
companyAddress: "",
companyRegNumber: "",
companyContactNumber: ""
});
})
.catch((err) => {
setCompanyLoading(false);
setCompanyErrorMsg(err.response.data.errorMsg)
})
}
};
const handleCompanyLogo = (evt) => {
setCompanyLogo(evt.target.files[0])
};
frontend view
<form className="register-form" onSubmit={handleCompanySubmit} noValidate>
<label className="text-secondary">Company Logo :</label>
<input type="file" className="form-control" onChange={handleCompanyLogo}/>
//remaining input fields
<button className="btn btn-info submitButton" >Submit</button>
</form>
api for adding company
export const addCompany = async (data) => {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const response = await axios.post(
"http://localhost:5000/api/auth/clients/company",
data,
config
);
return response;
};
controller in backend
exports.addNewCompany = async(req,res)=>{
const {
companyName,
companyAddress,
companyRegNumber,
companyContactNumber,
companyLogo
} = req.body;
const company = await Company.findOne({ companyName });
if (company) {
return res.status(400).json({
errorMsg: `${req.body.companyName} already exists`,
});
}
try{
const newCompany = new Company();
newCompany.companyName = companyName;
newCompany.companyAddress = companyAddress;
newCompany.companyRegNumber = companyRegNumber;
newCompany.companyContactNumber = companyContactNumber;
newCompany.companyLogo = companyLogo;
await newCompany.save();
res.json({
successMsg: `${req.body.companyName} Company Added Successfully`
});
} catch (err) {
console.log("clientsController error - Add Company ", err);
res.status(500).json({
errorMsg: "Server Error. Please Try again",
});
}
};
The error i get in the console is this
clientsController error - Add Company Error: Company validation failed: companyLogo: Path companyLogo is required.
at ValidationError.inspect
(C:\CCP\sd08_2021\Backend\node_modules\mongoose\lib\error\validation.js:47:26)
Can you please help me out ?
I think that your error is caused by a more trivial problem :
When you send the POST request with fetch, you don't actually wait for its completion (it's a promise), so the code in the if ... else {...} statement is executed before the termination of the fetch() !
setCompanyLogoURL(data.url) has not been called yet, so formData.append('companyLogo', companyLogoURL); set a blank string instead of the value returned by the call to the Cloudinary API.
The solution would be to make handleCompanySubmit async, and to await for the fetch() promise completion.
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.
I have spent a lot of time debbuging the following problem but it isn't fixed. The problem occur whenever I the user click on the button and window.locatoin.redirect and window.location.assign methods don't work.
Here is my Code index.ejs:
function registration() {
$.post('/user/register', {
teamName: $('#teamName').val(),
faculty: $('#faculty').val(),
email: $('#emailSignUp').val(),
password: $('#passwordSignUp').val()
}).done(
window.location.assign('/scoreboard')
)
}
router.js:
router.post('/user/register', (req, res) => {
var newUser = {
teamName: req.body.teamName,
faculty: req.body.faculty,
email: req.body.email,
password: req.body.password
}
userModel.create(newUser, (err, user) => {
if (err) {
console.log('[Registratoin]: ' + err);
} else {
console.log('[Registration]: Done');
req.session.userID = user._id;
res.redirect('/scoreboard')
}
});
})
router.get('/scoreboard', (req, res) => {
userModel.find({}).sort('-score').exec((err, teams) => {
if (err) {
console.log('[scoreboard]: ' + err)
}
else{
res.render('main/scoreboard', {
teamInformation: teams
}
)
}
})
})
When I test the code, I see the [Registration]: Done logged correctly. but redirect doesn't work. How should I fix it?
Please using location.href instead of location.assign as below:
window.location.href = "/scoreboard";
HTML5 introduced the history.pushState() and history.replaceState() methods, which allow you to add and modify history entries, respectively.
history.pushState(null, null, "/scoreboard")
More information about the new features of HTML5 to handle these kind of problem are available here.
I have an ExpressJS app that when a user makes a POST request to a route, it should lookup the ID in the MongoDB using req.params.formId
I have some console.log statements tfor debugging and so I can see what info is being returned.
The route should lookup the ID passed and when it finds it, use the req.body data and also a field from the MongoDB document but this just seems to return as undefined
Here is the code for the route:
app.post("/api/v1/forms/:formId", (req, res) => {
const { name, email, message } = req.body;
console.log(req.body);
Form.findById(req.params.formId, Form.recipient, err => {
if (err) {
res.send(err);
} else {
const formRecipient = Form.recipient;
const newForm = {
name,
email,
message,
recipient: formRecipient
};
console.log(newForm);
const mailer = new Mailer(newForm, contactFormTemplate(newForm));
try {
mailer.send();
res.send(req.body);
} catch (err) {
res.send(err);
}
}
});
});
So an example, if I make a POST request to localhost:5000/api/v1/forms/5ad90544883a6e34ec738c19 the console.log of newForm shows { name: ' Mr Tester',
email: 'person#example.com',
message: 'Hi there',
recipient: undefined }
The forms Mongoose schema has a field named recipient
the correct way is to provide the fields you want to get as the second argument:
Form.findById(req.params.formId, 'recipient', (err, form) => {
if (err) {
// error handling code
} else {
const formRecipient = form.recipient;
}
...
});
here's the Docs
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!');
});
})