Reputation: 317
I'm creating a personal project. I choose Passport.js for authentifications and I would like to update user's profile using this mongoose schema :
var userSchema = mongoose.Schema({
local : {
email : {type: String, required: true, unique: true},
password : {type: String, required: true}
},
first_name : {type: String, required: true},
last_name : {type: String, required: true},
username : {type: String, required: true, unique: true},
email : {type: String, required: true, unique: true}});
Here, the post route that I use :
app.post('/editProfile', isLoggedIn, function(req, res, next){
User.update({ _id: req.user.id}, req.body, function(err, user){
if(!user){
req.flash('error', 'No account found');
return res.redirect('/edit');
}
var emailEdit = req.body.email;
var usernameEdit = req.body.username;
var first_nameEdit = req.body.firstname;
var last_nameEdit = req.body.lastname;
if(emailEdit.lenght <= 0 || usernameEdit.lenght <= 0 || first_nameEdit.lenght <= 0 || last_nameEdit.lenght <= 0){
req.flash('error', 'One or more fields are empty');
res.redirect('/edit');
}
else{
user.email = emailEdit;
user.local.email = emailEdit;
user.first_name = first_nameEdit;
user.last_name = last_nameEdit;
user.username = usernameEdit;
res.redirect('/profile/');
}
});
When I run it, I have an error and I don't understand why
TypeError: Cannot set property 'email' of undefined
because of user.local.email = emailEdit;
When I comment this line, only username is updated.
I'm sure it's a stupid mistake that I did but I can't find it.
I'm also looking for an eventual much more efficient way to update profile using passport, node and mongo. And if possible a dynamic one which, for example, I could check in realtime if username is not already taken and set the field in red in this case.
Upvotes: 2
Views: 9292
Reputation: 418
const updateUser = (req ,res, next)=>{
const updateData = req.body.update;
if (!updateData){
res.status(422).send({"message":"please provide what you want to update"})
}
User.findOne({email:req.body.user.email}).then(function(user) {
if (!user) { return res.sendStatus(401); }
//NOTE only update fields that were actually passed...
if (typeof updateData.username !== 'undefined') {
user.username = updateData.username;
}
if (typeof updateData.email !== 'undefined') {
user.email = updateData.email;
}
if (typeof updateData.first_name !== 'undefined') {
user.email = updateData.email;
}
if (typeof updateData.last_name !== 'undefined') {
user.email = updateData.email;
}
if (typeof updateData.bio !== 'undefined') {
user.bio = updateData.bio;
}
if (typeof updateData.image !== 'undefined') {
user.image = updateData.image;
}
if (typeof updateData.password !== 'undefined') {
user.setPassword(updateData.password);
}
return user.save()
.then(function() {
return res.json({ user: user.toAuthJSON() });
});
}).catch(()=>{
res.status(422).send({"message":"couldn't update user"})
}
);
};
UserSchema.methods.generateJWT = function() {
var today = new Date();
var exp = new Date(today);
exp.setDate(today.getDate() + 60);
return jwt.sign({
id: this._id,
username: this.username,
exp: parseInt(exp.getTime() / 1000),
}, config.secret);
};
UserSchema.methods.toAuthJSON = function() {
return {
username: this.username,
email: this.email,
token: this.generateJWT(),
bio: this.bio,
avatar: this.image
};
};
Upvotes: 0
Reputation: 6766
Model.update's callback does not return a document.
In your case, I would just use findById
and save
.
app.post('/editProfile', isLoggedIn, function(req, res, next){
User.findById(req.user.id, function (err, user) {
// todo: don't forget to handle err
if (!user) {
req.flash('error', 'No account found');
return res.redirect('/edit');
}
// good idea to trim
var email = req.body.email.trim();
var username = req.body.username.trim();
var firstname = req.body.firstname.trim();
var lastname = req.body.lastname.trim();
// validate
if (!email || !username || !firstname || !lastname) { // simplified: '' is a falsey
req.flash('error', 'One or more fields are empty');
return res.redirect('/edit'); // modified
}
// no need for else since you are returning early ^
user.email = email;
user.local.email = email; // why do you have two? oh well
user.first_name = firstname;
user.last_name = lastname;
user.username = username;
// don't forget to save!
user.save(function (err) {
// todo: don't forget to handle err
res.redirect('/profile/');
});
});
});
Upvotes: 3