I have the following code to update Users information by Id:
router.put("/:id", async (req, res) => {
if (req.body.userId === req.params.id || req.body.isAdmin) {
if (req.body.password) {
try {
const salt = await bcrypt.genSalt(10);
req.body.password = await bcrypt.hash(req.body.password, salt);
} catch (err) {
return res.status(500).json(err);
}
}
try {
await User.findByIdAndUpdate(req.params.id, { $set: req.body });
res.status(200).json("Account has been updated");
} catch (err) {
return res.status(500).json(err);
}
} else {
return res.status(403).json("You can update only your account!");
}
});
I pass the new fields and findByIdAndUpdate is returning the catch error, I'm new to node and following a tutorial.
Related
I am trying to delete a collection from mongodb using postmap API. Below is my code.The update function is working fine.But, delete function isn't working. It's displaying internal server error.I dont know why?
const router = require("express").Router();
const User = require("../models/User");
const bcrypt = require("bcrypt");
//uodate
router.put("/:id", async (req, res) => {
if ((req.body.userId === req.params.id) || req.body.isAdmin) {
if (req.body.password) {
try {
const salt = await bcrypt.genSalt(10);
req.body.password = await bcrypt.hash(req.body.password, salt);
}
catch (err) {
return res.status(500).json(err);
}
}
try {
const user = await User.findByIdAndUpdate(req.params.id, {
$set: req.body,
});
return res.status(200).json("Account has been updated");
}
catch (err) {
return res.status(500).json(err);
}
}
else return req.status(400).json("You can only update your account!!!");
});
//delete
router.delete("/:id", async (req, res) => {
if ((req.body.userId === req.params.id) || req.body.isAdmin) {
try {
await User.deleteOne(req.params.id);
return res.status(200).json("Account has been deleted");
}
catch (err) {
return res.status(500).json(err);
}
}
else return res.status(400).json("You can only update your account!!!");
});
module.exports = router;
Help me with thispostman API screenshot.
Try this:
await User.deleteOne({_id:req.params.id});
You are using deleteOne() method. If you want to delete whole collection, you should use deleteMany() method:
await User.deleteMany({});
The Model.deleteOne method expects a filter object, like {name: "value'"}. You are passing req.params.id which is a string. If you dig out the full text of the error, it will likely complain about that string not being an object.
You probably meant to use the Model.findByIdAndDelete method like
await User.findByIdAndDelete(req.params.id);
As the name states, I keep getting a "Query was already executed" while running Mongoose.find queries. Using '.clone' does not seem to be fixing the issue...
My calling code is:
let result = mongo.isValidUsername(req.body.username).then((data) => {
return data;
});
if ((await result) == false) {
res.send("Sorry, that username is unavailable");
} else {
mongo
.addUser(
req.body.username,
req.body.password,
req.body.firstName,
req.body.lastName,
req.body.email,
req.body.phoneNumber
)
.then(() => {
let profileData = mongo.getProfileData(req.body.username);
profileData
.then((data) => {
res.render("accountDisplay", {
results: data,
trans: [9.99],
});
})
.catch((err) => {
console.log(err);
});
});
}
I call a query twice - Once in isValidUsername() at the beginning (where I have not used .clone) and then again in getProfileData( where I HAVE used .clone).
I keep getting this error. Any idea what could be causing it?
Here is the code for isValidUsername() and getProfileData(), just in case...
async function isValidUsername(usernameToQuery) {
//connect to mongoose database
mongoose.connect("mongodb://localhost:27017/bankDB");
try {
let isValid = UserModel.findOne({ username: usernameToQuery }).then(
(data) => {
if (data == null) {
return true;
} else {
return false;
}
}
);
return await isValid;
} catch (err) {
return err;
}
}
async function getProfileData(usernameToQuery) {
mongoose.connect("mongodb://localhost:27017/bankDB");
let profileData = UserModel.findOne({ username: usernameToQuery }).clone();
console.log(await profileData);
let profileArray = await profileData.then((data) => {
return [
data._doc.firstName,
data._doc.lastName,
data._doc.email,
data._doc.phoneNumber,
];
});
return await profileArray;
}
I've got myself two functions, first is responsible for adding a user model to database and second one for comparing passwords. But.. comparing never works..
module.exports.signup = function (req, res) {
if (req.body == null) {
res.status(400);
return res.end('Bad juju');
} else {
let exists;
User.findOne({ username: req.body.username }),
(err, doc) => {
if (doc) {
exists = true;
return;
}
};
if (exists) {
res.setHeader('user-exists', true);
res.redirect('/signup');
} else {
bcrypt.hash(req.body.password, 10, function (hashE, hash) {
if (hashE) {
throw hashE;
}
new User({
username: req.body.username,
email: req.body.email,
password: hash,
}).save();
});
return res.redirect('/login');
}
}
};
module.exports.login = function (req, res) {
if (req.body.tosignup) {
return res.redirect('/signup');
}
if (req.body == null) {
res.status(400);
return res.end('Bad request');
} else {
User.findOne({ username: req.body.username }, (err, doc) => {
if (err) throw console.log(err);
console.log(doc.password);
console.log(req.body.password);
bcrypt.hash(req.body.password, 10, (err, s) => {
console.log(s);
});
bcrypt.compare(req.body.password, doc.password, (err, succ) => {
if (err) {
throw err;
}
console.log(err);
console.log(succ);
if (succ) {
res.setHeader('username', doc.username);
return res.redirect('/welcome');
} else {
res.setHeader('password-wrong', true);
return res.redirect('/login');
}
});
});
}
};
I've looked for different sources and all of them told that this one method is the correct one, but every time I try using it, it just doesn't work
I had a similar problem using bcrypt in nodejs. To solve the problem i switched from npm bcrypt to npm bcryptjs (https://www.npmjs.com/package/bcryptjs) and used the following:
NPM require:
const bcrypt = require('bcryptjs');
To compare the passwords you can use the following code:
async function compareIt(password, hashedPassword) {
const validPassword = await bcrypt.compare(password, hashedPassword);
return validPassword;
}
compareIt(password, passwordBD).then(v => {
if (v == true) {
console.log("Equal");
} else {
console.log("Not equal");
}
});
To hash the password you can use this function:
async function hashIt(password) {
const salt = await bcrypt.genSalt(6);
const hashed = await bcrypt.hash(password, salt);
return hashed;
}
I can use ctx.body in find()'s callback:
router.post("/register/isNameUsed", async (ctx, next) => {
let username = ctx.request.body.username;
await userInfo.find({ username: username }, function(err, doc) {
if (err) {
console.log(err);
} else {
if (doc.length > 0) {
ctx.body = { isNameUsed: true };
} else {
ctx.body = { isNameUsed: false };
}
}
});
await next();
});
But I can't use it in save()'s callback:
router.post("/register", async (ctx, next) => {
let username = ctx.request.body.name;
let password = ctx.request.body.password;
var ui = new userInfo({
username,
password
});
await ui.save(function(err, doc) {
if (err) {
console.log(err);
} else {
ctx.body = { registerSuccess: true };//It doesn't work
}
});
await next();
});
The code runs successfully,just the ctx.body doesn't work, why?
OK,I changed my code to this:
router.post("/register", async (ctx, next) => {
let username = ctx.request.body.name;
let password = ctx.request.body.password;
var ui = new userInfo({
username,
password
});
try {
let insertRes = await ui.save();
ctx.body = { registerSuccess: true };
} catch (error) {
ctx.body = { registerSuccess: false };
}
await next();
});
Then the ctx.body worked.
And I'll never write ctx.body in the callback, it's so queasily...
But I still don't know why the ctx.body can work in the find()'s callback but not in the save()s?
Postman is returning error whenever i include this pre() function,
it returns an error else its working and everything is getting stored in db using mongodb.
Is there something wrong in ES6 format that i have used or any other?
Below is the code :
// userschema is the name of the schema //
// SALT_I = 10 //
userSchema.pre('save', next => {
if (this.isModified('password')) {
bcrypt.genSalt(SALT_I, (err, salt) => {
if (err)
return next(err)
bcrypt.hash(this.password, salt, (err, hash) => {
if (err)
return next(err)
this.password = hash
next()
})
})
} else
next()
})
here is the postman error:
{
"success": false,
"err": {}
}
and it is as i am making a post request using the function:
app.post('/api/users/register', (req, res) => {
const user = new User(req.body)
user.save((err, data) => {
if (err) return res.json({ success: false, err })
res.status(200).json({
success: true,
userdata: data
})
})
})
You cannot use ES6 spread operator but ES5 syntax works just fine:
userSchema.pre('save', function (next) {
const user = this
if (user.isModified('password')) {
bcrypt.genSalt(SALT_I, function (err, salt) {
if (err) {
console.log("inside gensalt if")
return next(err)
}
bcrypt.hash(user.password, salt, function (err, hash) {
if (err) {
console.log("inside bcrpt hash")
return next(err)
}
user.password = hash
next()
})
})
} else
next()
})