I'am new with node.js.I Need to save data from HTML page use - form (user name, password, email e.t.c)in Mongodb. I have this code:
var Schema = new mongoose.Schema({
_id : String,
name: String,
age : Number
});
var user = mongoose.model('emp', Schema);
app.post('/new', function(req, res){
new user({
_id : req.body.email,
name: req.body.name,
age : req.body.age
}).save(function(err, doc){
if(err) res.json(err);
else res.send('Successfully inserted!');
});
});
<form action="/new" method="POST">
<label for="email">Email: </label>
<input type="email" name="email" /><br />
<label for="name">Name: </label>
<input type="text" name="name" /><br />
<label for="age">Age: </label>
<input type="number" name="age" /><br />
<input type="submit"/>
When I run server. Trying to save some data. I see message
"Cannot read property 'email' of undefined"
"TypeError: Cannot read property 'email' of undefined"
Somebody help me please with this misunderstood. Thans a lot!
Also you don't need to define _id in your schema, it gets automatically created. Maybe you meant to define email : String so it matches your req.body.email
Related
I already created my model 'order'
I try to add new order into my mongodb, but keep showing this error,please help me! Thanks
I rely on the add_order.ejs to submit the form.
"ReferenceError: Cannot access 'order' before initialization"
I have the other two model 'recipe' and 'customer',but they worked! I don't understand why only
order has error?
order.js
const userSchema = new mongoose.Schema({
order_id :{
type: String,required : true
},
sum :{
type:Number,
required : true,
},
account :{
type :String,
required : true,
}
});
module.exports = mongoose.model('order',userSchema);
routes.js
const express = require('express');
const mongoose = require('mongoose');
const router = express.Router();
const customer = require('../models/customer');
const recipe = require('../models/recipe');
const multer = require('multer');
const { GridFSBucketReadStream } = require('mongodb');
const fs = require('fs');
const order = require('../models/order');
//insert an order into database route
router.post('/add_order', upload, (req,res) => {
const order = new order({
order_id : req.body.order_id,
sum : req.body.sum,
account : req.body.account,
});
order.save((err) => {
if(err){
res.json({message : err.message, type :'danger'});
}
else{
req.session.message={
type:'success',
message :'Customer added successfully!'
};
res.redirect("/");
}
})
})
add_order.ejs
<form action="/add_order" method="POST" id="add-form" enctype="multipart/form-data">
<div class="one_third first">
<label for="name">order_id <span>*</span></label>
<input type="text" name="order_id" placeholder="Enter order_id" size="22" required /></td>
</div>
<div class="one_third">
<label for="email">sum <span>*</span></label>
<input type="number" name="sum" placeholder="Enter sum" size="22" required>
</div>
<div class="one_third">
<label for="url">account <span>*</span></label>
<input type="text" name="account" placeholder="Enter account" size="22" required />
</div>
<input type="submit" name="submit" value="Add order" />
<input type="reset" name="reset" value="Reset Form">
</form>
You have a problem on this:
const order = require('../models/order');
//insert an order into database route
router.post('/add_order', upload, (req,res) => {
const order = new order**({ // <- you trying to change an immutable class definition
Class variable and instance variable needs to have different names.
Recommend you to change your class name to Order (with capital O):
const Order = require('../models/order');
then call your instance like this:
const order = new Order({ ... });
See more
I'm having trouble sending data to the server using a form. I already made a register form that works just fine, and for the most part my client side javascript for the login form is very similar to the javascript for the register form, and I just can't figure out why it won't work. It just gives me "Cannot POST /login.html"
Here's the login form html:
<div class="loginTitle">
<h1>Login</h1>
</div>
<div class="loginFormLayout">
<form method=post id="loginForm">
<div class="loginFormText">
<label for="username">Username</label>
</div>
<div class="loginFormEntry">
<input type="text" placeholder="Enter Username" name="loginUsername" required>
</div>
<div class="loginFormText">
<label for="password">Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Enter Password" name=loginPassword required>
</div>
<button type="submit" class="loginButton">Log In</button>
</form>
</div>
And here's the client side javascript:
//Login as an existing user
const login = document.getElementsByClassName('loginButton');
const loginForm = document.getElementById('loginForm');
const loginURL = 'http://localhost:3000/loginUser';
loginForm.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(loginForm);
let username = formData.get('loginUsername');
let password = formData.get('loginPassword');
loginForm.reset();
let user = { //Create a user object that will be sent to the backend and compared to the user database
username,
password
};
fetch(loginURL, { //Send the user object to the backend in JSON format to be checked against the database
method: 'POST',
body: JSON.stringify(user),
headers: {
'content-type': 'application/json'
}
})});
And the server side javascript for now, console logs are just to see if the info is getting up to the server
app.post('/loginUser', (req, res) => {
console.log(req.body.username);
console.log(req.body.password);
});
EDIT: I've also decided to post the info for my register form, which DOES work and uses similar logic to the login form. Maybe I'm missing something that isn't in the login logic
Register form html:
<div class="loginMenu">
<div class="loginTitle">
<h1>Register</h1>
</div>
<div id="registerWarning"></div>
<div class="loginFormLayout">
<form method="post" id="registerForm">
<div class="loginFormText">
<label for="username" id="newUsername">Username</label>
</div>
<div class="loginFormEntry">
<input type="text" placeholder="Create Username" name="username" required>
</div>
<div class="loginFormText">
<label for="password" id="newPassword">Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Create Password" name=password required>
</div>
<div class="loginFormText">
<label for="confirmPassword">Confirm Password</label>
</div>
<div class="loginFormEntry">
<input type="password" placeholder="Confirm Password" name="confirmPassword" required>
</div>
<button type="submit" class="registerButton">Register</button>
</form>
</div>
</div>
Register form client side javascript:
//Register a new user
const register = document.getElementsByClassName('registerButton');
const registerForm = document.getElementById('registerForm');
const registerURL = 'http://localhost:3000/createNewUser';
//When the user presses the register button, get the info from the form
registerForm.addEventListener('submit', (event) => {
event.preventDefault();
const formData = new FormData(registerForm);
let newUsername = formData.get('username');
let newPassword = formData.get('password');
let confirmPassword = formData.get('confirmPassword')
registerForm.reset();
//Make sure new password and confirm password are equal
if (newPassword == confirmPassword) {
if (newUsername != "" && newPassword != ""){ //Make sure user enters something for both fields
let newUser = { //Create an object to send to the back end
newUsername,
newPassword
};
fetch(registerURL, { //Send the newUser object to the backend in JSON format to be added to the database
method: 'POST',
body: JSON.stringify(newUser),
headers: {
'content-type': 'application/json'
}
});
}
}
else { //If newPassword and confirmPassword are not equal, ask the user to enter them correctly
const registerWarning = document.getElementById('registerWarning');
registerWarning.innerText = 'Password and Confirm Password do not match';
registerWarning.style.padding = "10px";
registerWarning.style.background = 'red';
};
});
Register form server-side javascript:
app.post('/createNewUser', (req, res) => {
let newUsername = req.body.newUsername;
let newPassword = req.body.newPassword;
let newUserData = 'INSERT INTO users (username, password) VALUES (?, ?)';//Use the question marks as placeholders
//Use bcrypt to hash the password before putting it in the database
bcrypt.hash(newPassword, saltRounds, function(err, hash) {
db.query(newUserData, [newUsername, hash], function(err, result) {
if (err) throw err;
console.log('New user registered');
});
});
});
I figured it out, thanks to #Rocky Sims for the help.
Basically, the register form doesn't exist on the login html page, which was throwing an error up about how that doesn't exist before it could even get to the login code. So I just had to make seperate register.js and login.js files, as the issue was due to them being in the same file.
Try wrapping your form method (post) in quotes ('') like so <form method='post' id="loginForm">
Also the value for the name attribute for your password input should by in quotes. Like so <input type="password" placeholder="Enter Password" name='password' required>
I think the problem is that you haven't told the server what to send back to the client when the POST /loginUser endpoint gets called. Try adding res.sendStatus(200); at the end of your POST /loginUser handler function (so right after console.log(req.body.password);).
I'm trying to implement authentification system with express + node js. So far it's been good, but now I see that even when I refresh the page, the form submits to the server. This is how my code looks like:
Client side:
submit(e) {
let data = this.state; /// object with user's informations
e.preventDefault()
validate.form(this.state.username, this.state.email, this.state.password, this.state.confirm) // this returns true if everything is fine or returns the error string!
}
render() {
return (<div>
<form action="/login" onSubmit = {this.submit} method="post">
<p>Username:</p>
<input type="text" onChange = {this.getData} name="username" value = {this.state.username} />
<p>Email</p>
<input type="text" onChange={this.getData} name = "email" value = {this.state.email} />
<p>Password</p>
<input type="text" onChange={this.getData} name = "password" value = {this.state.password} />
<p>Confirm Password</p>
<input type="text" onChange={this.getData} name = "confirm" value = {this.state.confirm} />
<br/> <br/>
<input type="Submit" value='Submit' /> ///this is not working!
</form>
</div>)
}
Server side:
app.post('/login',(req, res) => {
console.log(req.body)
res.sendFile(__dirname + '/src/index.html')
db.query('INSERT INTO users SET ?', req.body, (err, res) => console.log("done!"))
})
TL;DR I'm looking to submit the form only if validate.form(username, email, password, confirm) returns true. I'm using bodyParser as module to parse the json!
Assuming that form.validate() is synchronous, you should call preventDefault only if form.validate() returns the error string.
submitForm(e) { // avoid to use 'submit' as method name
let data = this.state; /// object with user's informations
let formValid = validate.form(this.state.username, this.state.email, this.state.password, this.state.confirm);
if(formValid !== true) {
e.preventDefault()
}
// else, if formValid is true, the default behaviour will be executed.
}
Currently, I am using ng-model to insert data into my MongoDB. Is there a way to use ng-model to insert data into an array in MongoDB? answers is an array that should contain 4 strings that the user enters. I tried adding [0], [1], [2], [3] to quiz.quizData.answers but it did not enter the data correctly as an array. Instead it entered it like this:
"answers" : [
{
"0" : "My First Answer",
"1" : "My Second Answer"
}
],
instead of how it should be:
"answers" : [
"My First Answer",
"My Second Answer"
],
My HTML input form:
<input type="text" name="answers" ng-model="quiz.quizData.answers" placeholder="enter answers here" required>
<input type="text" name="answers2" ng-model="quiz.quizData.answers" placeholder="enter other answers here" required>
My End Point
// POST request for users to post a new quiz entry
apiRouter.route('/quiz')
.post(function(req, res) {
// Create quiz object and assign to 'quiz'
var quiz = new Quiz();
// Contains the quiz question
quiz.question = req.body.question;
// Contains an array with four quiz answers
quiz.answers = req.body.answers;
// Contains one string that matches the correct answer from the array above
quiz.correctAnswer = req.body.correctAnswer;
// Identifies user creating the quiz
quiz.postedBy = req.body.postedBy;
// Identifies the category of the quiz
quiz.category = req.body.category;
// then save new quiz to database
quiz.save(function(err) {
// If an error occurs, display error message in JSON format
if (err) {
return res.json({ success: false, message: 'something went way wrong....' + err });
} else {
// If no error occurs and it saves, display success
res.json({ message: 'Quiz Created!' });
}
});
});
My MongoDB Schema:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
// post schema
var QuizSchema = new Schema({
question: { type: String, lowercase: true, required: true },
answers: { type: Array, required: true },
correctAnswer: { type: String, required: true },
category: { type: String, lowercase: true, required: true },
postedBy: { type: String, required: true }
});
module.exports = mongoose.model('Quiz', QuizSchema);
You can just use ng-repeat iterating a range if you're starting with an empty array:
<input ng-repeat="i in [1,2,3,4]" type="text" name="answers{{i}}" ng-model="quiz.quizData.answers[i]" placeholder="enter answers here" required>
If your array already exists, and you want to account for variable array length you can use ng-repeat and $index. Make sure you add track by $index or you will encounter an issue with duplicate keys:
<input ng-repeat="answer in quiz.quizData.answers track by $index" type="text" name="answers{{$index}}" ng-model="quiz.quizData.answers[$index]" placeholder="enter answers here" required>
https://plnkr.co/edit/dwHIFTftgq5LFfTOpc9X?p=info
HTML
<input type="text" name="answer1" ng-model="answersArray[0]" placeholder="answer 1">
<input type="text" name="answer2" ng-model="answersArray[1]" placeholder="answer 2">
<input type="text" name="answer3" ng-model="answersArray[2]" placeholder="answer 3">
<input type="text" name="answer4" ng-model="answersArray[3]" placeholder="answer 4">
<input type="hidden" name="answers" ng-model="quiz.quizData.answers" placeholder="enter answers here" ng-init="quiz.quizData.answers = answersArray">
Controller
$scope.answersArray = [
answer1 = $scope.answer1,
answer2 = $scope.answer2,
answer3 = $scope.answer3,
answer4 = $scope.answer4
];
I am trying to do a Post request to my NodeJs server using PostMan and the terminal, but it seems the request never ends.
I have a website and a form, and I try to send the form by using Ajax. I do the same thing in other file except the fact that the other file does not contain a form and the post works.
This is my html form:
<div class="team">
<img class="teamInfo" src="images/leaderboard.png">
<p class= "createT"> Create a Team </p>
<p class= "chooseC"> Choose a Charity </p>
<p class= "enter"> Enter Team Member's Email</p>
<p class= "upload">Upload your Company<br>or Team's Logo</p>
<!-- added action tag solved the 405 error : "post method not allowed"-->
<form id="create_team_form" action="/" method="post">
<input class="teamName" type="text" id="teamName" name="teamName" size="25" maxlength="60" value="Team Name">
<input class="companyName" type="text" id="companyName" name="companyName" size="25" maxlength= "60" value="Company Name">
<input class="teamDescription" type="text" id="teamDescription" name="teamDescription" size="25" maxlength= "60" value="Team Description">
<input class= "email" type="text" id="email" name="email" size="25" maxlength= "60" value="emails">
<input class="searchCharity" type="text" id="charityName" name="charityID" size ="25" maxlength="60">
<p class="click"> Click the charity's name to select who your team will run for!</p>
<input class="greenButton" type="button" onclick="createTeam();" value="Create My Team!">
</form>
<img class="img-box" src="images/imgBox.png" alt=""/>
</div>
This is my javascript ajax to send the form to the server:
function createTeam(){
var teamN= document.getElementById("teamName").value;
var companyName =document.getElementById("companyName").value; //maybe not, tae it off.
var charityName = document.getElementById("charityName").value;
if((teamN.trim() === "") || (companyName.trim() === "") || (charityName.trim() === ""))
{
alert("You did not fill the team Name or companyName, Please enter with a name");
}else{
var sessionID = $.cookie("sessionID")
$.ajax({
type: "POST",
url: "http://xxx.xxxx.xxx.x:9000/team/?sessionID="+sessionID,
data: $("#create_team_form").serialize(),
success: function(msg) {
alert("team supposedly saved")
$.cookie("teamID",msg.teamID)
$.cookie("sessionID",sessionID)
//window.location.href='teamCreated.html'
}
});
}
}
It goes inside the if, but the else is just slow. I don't know if the data is being sent. I could not save a document so far in my mongodb.
This is my team.js in the server:
var express = require('express');
var sha1 = require('sha1');
var router = express.Router();
var sessionOBJ = require('./session');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
router.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT, GET,POST");
});
var teamSchema = new Schema({
teamID: String,
teamName: String,
teamDescription: String,
teamAdminID: String,
teamLink: String,
charityID: String
});
var teamModel = mongoose.model('teams',teamSchema);
router.post('/', function (req, res){
log.d("Entrou no method post");
var sessionID = req.query.sessionID
var team = req.body;
var teamName = team.teamName;
var teamDescription = team.teamDescription;
var charityID = team.charityID;
var teamLink = team.teamLink;
sessionOBJ.isAuthorized(sessionID, function(sessionID){
log.d("Checking session to save team", sessionID);
var adminID = sessionID.userID;
var newTeam = new teamModel({
teamName: teamName,
teamDescription: teamDescription,
teamAdminID: adminID,
teamLink: teamLink,
charityID: charityID
});
newTeam.save(function(err, team){
if(err) return console.error(err);
res.send({"status" : "Created", "teamID" : team._id, "teamAdminID":team.teamAdminID });
log.d("Created Team ID", team._id)
log.d("XXXXXXX XXXXXX XXXXXXX Team Saved inside save method",team);
});
});
})
}
Does someone can see what I am doing wrong?
Thanks in advance.
After res.send() call res.end(). response.end tells the server that the entire message has been sent and can close the connection, otherwise, it'll wait for more data.
source:
https://nodejs.org/api/http.html#http_response_end_data_encoding_callback