to pass email id to ejs templete - node.js

I am trying to get the email to ejs template but not getting it. How to get the same email saved from mongoose to ejs template
First, I click on the mail icon to send mail to that selected email by nodemailer.
mailController.js
router.get('/donation/mail', async (req,res) => {
const donations = await Donation.findOne(({_id: id }), {new: true}, (err, doc) => {
if (err) {
console.log("");
}
console.log(doc);
});
res.redirect('/', {
donations
});
});
form.ejs
<div class="form-group">
<input type="text" class="form-control" placeholder="To" name="to" value="<%= donations.email %>">
</div>
mailModel.js
const donationSchema = new Schema({
email: {
type: String
}
})
module.exports = mongoose.model('donations', donationSchema);
error
GET /donation/mail 500 14.818 ms - 2401
Cannot read property 'email' of null
To get that email id from mongoose to ejs template like image

Related

How to login to a page using mongoDB post request isnt recognized?

Hi there im having difficulty with my post request for login,
I've managed to get register working and i redirect it to login so i can attempt, the account registered goes onto mongodb correctly, from some testing with multiple logs, turns out the post for login isnt effecting it, and it simply redirects again to login, unsure how that is
heres what i got
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true
},
password: {
type: String,
required: true
}
})
module.exports = mongoose.model('users', userSchema)
This is for where im storing the users info for the login page
<h1>Login</h1>
<form action="/login" method="GET">
<div>
<label for="name">Name</label>
<input type="name" id="name" name="name" required>
</div>
<div>
<label for="email">Email</label>
<input type="email" id="email" name="email" required>
</div>
<div>
<label for="password">Password</label>
<input type="password" id="password" name="password" required>
</div>
<button type="submit">Login</button>
</form>
Register a User
Register is the same as this only with the href relating to this login page
const express = require('express')
const router = express.Router()
const users = require('../models/users')
const book = require('../models/book')
router.get('/home', async (req, res) => {
let books
try {
books = await book.find().sort({ createdAt: 'desc' }).limit(10).exec()
} catch {
books = []
}
res.render('home.ejs', { books: books })
})
//Login user
router.get('/', (req, res) => {
res.render('index.ejs')
})
router.get('/login', async (req, res) => {
res.render('login')
})
router.post('/login', async (req, res) => {
console.log("HI")
try{
const valid=await users.findOne({name:req.body.name})
if (valid.password===req.body.password){
res.render('home')
}
else{
console.log("HI")
res.send("Incorrect Password Try again?")
res.render('home')
}
}catch{
console.log("HI")
res.render('home')
}
})
//Register and upload to DB
router.post('/', async (req, res) => {
const user = ({
name: req.body.name,
email: req.body.email,
password: req.body.password,
})
await users.insertMany([user])
res.redirect('/')
})
module.exports = router
In your form you have mentioned method as "GET" . It is a post request so method should be "POST".
<form action="/login" method="post">

Can't update model with mongoose schema

i'm trying to make an update functionality but it doesn't update the model :( First i make a get request to get the data from the server and populate it in form(handlebars)
so, here's the router:
router.get('/edit/:id', async (req, res) => {
const warum = await Warum.findById(req.params.id)
res.render('edit', warum);
});
router.post('/edit/:id', (req, res) => {
return Warum.findOneAndUpdate(req.params.id, { new: true }, {
title: req.body.title,
description: req.body.description,
})
.then(() => {
res.redirect('/warum');
})
.catch((err) => {
console.log(err);
});
});
that's the form:
<form method="post">
<h2>Beitrag bearbeiten</h2>
<ul class="noBullet">
<li>
<label for="title">Titel:</label>
<input type="text" name="title" value="{{title}}" />
</li>
<li>
<label for="description">Beschreibung:</label>
<textarea class="texterea" name="description">
{{description}}
</textarea>
</li>
<div>
<button class="login-button">save</button>
</div>
</ul>
</form>
and that's the schema:
const mongoose = require('mongoose')
const WarumSchema = new mongoose.Schema({
title: String,
description: String,
});
const Warum = mongoose.model('Warumschema', WarumSchema);
module.exports = Warum;
I tried to change the route from post to put, but then it says 404. After clicking the save button it just redirects me, but the result is not edited.

Update user profile page using mongoose express js

I am working on personal project. one of common functionality i am implementing is allowing users to update their profile but having hard time doing it.
here is what i did so far
form
<form
action="/users/doctor-profile?_method=PUT"
method="POST"
enctype="multipart/form-data"
>
<input type="hidden" name="_method" value="PUT" />
<div class="form-group">
<input
type="text"
class="form-control"
id="name"
name="name"
/>
</div>
<div class="form-group">
<label for="phone">Phone</label>
<input
type="tel"
class="form-control"
id="formGroupExampleInput"
name="phone"
/>
</div>
<div class="form-group">
<label for="exampleInputEmail1">Email</label>
<input
type="email"
class="form-control"
id="formGroupExampleInput"
name="email"
/>
</div>
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
here is my user model
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
});
const User = mongoose.model("User", UserSchema);
module.exports = User;
here is my post route
router.post("/users/doctor-profile", (req, res) => {
const { name, email,phone } = req.body;
const _id = ObjectId(req.session.passport.user._id);
console.log(_id)
USer.findOne({ _id: _id })
.then((user) => {
if (!user) {
req.flash("error_msg", "user not found");
res.redirect("/users/doctor-profile");
}
if (typeof name !== "undefined") {
user.name = name;
console.log(user.name);
}
if (typeof email !== "undefined") {
user.email = email;
}
if (typeof phone !== "undefined") {
user.phone = phone;
}
user.save().then((User) => {
req.flash("success_msg", "details updated successfully");
res.redirect("/users/profile");
});
})
.catch((err) => console.log(err));
});
console output
application running on port 5000
mongodb connection successfull
5ef5bc20261beb1e6c1c25a3
but it does not update fields in database.
try this:
user.save(function (err, resolve) {
if(err)
console.log('db error', err)
// saved!
});
You had a typo in your post route js file
here is the code you got the typo on:
USer.findOne({ _id: _id })
USer should be User

Cant Save to MongoDB database and using handlebars

this is my post request to save to mongdb database
router.post("/create", async (req, res) => {
const createJottings = new Jottings({
title: req.body.title,
jottings: req.body.jottings
});
try {
await createJottings.save();
res.json(createJottings);
} catch (err) {
res.json({ message: err });
}
});
it works fine on postman but now i am trying to render it using handlebars to the client. this is the form for the client side using handlebars
<div class="card card-body">
<h3>
Edit Jottings/Idea
</h3>
<form action="/jottings/create" method="get">
<div class="form-group">
<label for="title">
Title
</label>
<input type="text" name="title" class="form-control" required />
</div>
<div class="form-group">
<label for="title">
Jottings
</label>
<textarea name="Description" class="form-control" required></textarea>
</div>
<button type="submit" class="btn btn-primary">
Submit
</button>
</form>
</div>
the form actually loads but when i press submit it doesnt save to mongodb server
{{#each getJottings}}
<div class="card card-body mb-2">
<h4>
{{title}}
</h4>
<p>
{{jottings}}
</p>
<a href="/jottings/edit/{{id}}" class="btn btn-dark btn-block">
Edit
</a>
</div>
{{else}}
<p>
No Ideas and Jottings listed
</p>
{{/each}}
code that outlists saved data in the database if i create it using postman it works but with the form it doesnt.
overview of my jottings route
// Require Mongoose
const router = require("express").Router();
// Setup Models for Jotting
const Jottings = require("../models/jottings.model");
// Setting Endpoints For Routes
// Get All Jottings
router.get("/", async (req, res) => {
try {
const getJottings = await Jottings.find({}).sort({ date: "desc" });
res.render("jottings/index", {
getJottings: getJottings
});
} catch (err) {
res.json({ message: err });
}
});
// Getting routes to set form
router.get("/add", (req, res) => {
res.render("jottings/add");
});
// Get Specific Jottings
router.get("/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
await Jottings.findById(id, (err, jottings) => {
if (!id) {
res.json({ message: err });
} else {
res.json(jottings);
}
});
} catch (err) {
res.json({ message: err });
}
});
// Post to create New Jottings for form
router.post("/create", async (req, res) => {
const createJottings = new Jottings({
title: req.body.title,
jottings: req.body.jottings
});
try {
await createJottings.save();
res.json(createJottings);
} catch (err) {
res.json({ message: err });
}
});
router.get("/edit/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
const editJottings = await Jottings.findOne({ _id: id });
res.render("jottings/edit", {
editJottings: editJottings
});
} catch (err) {
res.json({ message: err });
}
});
// Patch to Edit Jottings for form
router.patch("/edit/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
const editJottings = await Jottings.updateOne(
{ _id: id },
{ $set: { jottings: req.body.jottings } }
);
res.render("jottings/edit", {
editJottings: editJottings
});
} catch (err) {
res.json({ message: err });
}
});
// Delete to delete Jottings for form
router.delete("/delete/:id", async (req, res) => {
try {
// Requesting for request paremeter given to ever document created in mongoDB
const id = req.params.id;
const deleteJottings = await Jottings.deleteOne({ _id: id });
res.json(deleteJottings);
} catch (err) {
res.json({ message: err });
}
});
// Exporting router
module.exports = router;
i would like the details to be saved to the database when i click the submit button and also redirect me to a list of my saved details.
You form uses method GET while you defined router.post to handle form submission.

bcrypt.compareSync is always returning false

I verified that in my db I am saving the username and hash of the password. I am able to retrieve the name from the db, however when I check the password it always returns false. Not sure what is wrong.
Here is my HTML
<div ng-controller="userController">
<div class=user>
<form name="login_form">
<h2 class>Login</h2>
<h3 class = "login_page">UserName</h3>
<input ng-model="user" type="text" ng-minlength="1" required>
<h3 class = "login_page">Password</h3>
<input ng-model="password" type="password" name="password" ng-minlength="4" required>
<input type="submit" value="Login" ng-click="login()" >
<div ng-if ="login_form.$submitted" ng-messages="login_form.password.$error" style="color:maroon" role="alert">
<div ng-message="minlength">Your field is too short</div>
</div>
<p ng-if="error">Username or login is incorrect</p>
</form>
</div>
<div class=user>
<form name = "register_form">
<h2 class>Register</h2>
<h3 class = "login_page">UserName</h3>
<input ng-model="reg.name" type="text" required>
<h3 class = "login_page">Password</h3>
<input ng-model="reg.password" type="password">
<input type="submit" value="Register" ng-click="register()" required >
<div ng-if ="login_form.$submitted" ng-messages="login_form.password.$error" style="color:maroon" role="alert">
<div ng-message="minlength">Your field is too short</div>
</div>
<p ng-if="duplicate">That user name is taken, please choose another</p>
<p ng-if="correct">Registration Succesfull</p>
</form>
</div>
</div>
Here is my controller on the server side
var mongoose = require('mongoose'),
Todo = mongoose.model('Todo');
Login = mongoose.model('Login');
var bcrypt = require('bcrypt');
var name = ""
module.exports = (function(){
return {
save_name:function(req, res){
req.session.user = req.body.user
Login.findOne({name: req.body.user},
function(err, user) {
if(user){
console.log(user.password);
console.log( bcrypt.compareSync(req.body.password, user.password));
res.json({'error': false});
}else {
res.json({'error': true});
}
})
}, //end of save name method
register:function(req, res){
bcrypt.hashSync(req.body.password, bcrypt.genSaltSync(8));
login = new Login({
name:req.body.user,
password: bcrypt.genSaltSync(8)
})
login.save(function(err){
if(err){
res.json({'error': true});
} else {
res.json({'sucess': true})
}
})
} // end of register user function
}
})();
You're saving a generated salt as the password instead of the actual hash itself. Also, explicitly calling genSalt*() is unnecessary. Lastly, you really should use the async functions instead, to avoid unnecessarily blocking the event loop. So with all of this in mind, you may end up with something like:
module.exports = {
save_name: function(req, res) {
req.session.user = req.body.user;
Login.findOne({ name: req.body.user },
function(err, user) {
if (err)
return res.json({ error: true });
bcrypt.compare(req.body.password,
user.password,
function(err, valid) {
res.json({ error: !!(err || !valid) });
});
});
}, // end of save name method
register: function(req, res) {
bcrypt.hash(req.body.password, 8, function(err, hash) {
if (err)
return res.json({ error: true });
login = new Login({
name: req.body.user,
password: hash
})
login.save(function(err) {
res.json({ error: !!err });
})
});
} // end of register user function
};
Despite other answers, if it is still not resolving your issue. Try by applying the toString() when passing the password upon login like this.
req.body.password.toString();
The immediate cause of your bug is in register you should be using bcrypt.hashSync(myPlaintextPassword, saltRounds) instead of genSaltSync. Fixing that should make things "work".
However, you need to recode all this to use the async bcrypt APIs or your application will respond very poorly under load (like crippled and unusable, not just "slow"). General rule: no sync calls in a node.js server.

Resources