简体   繁体   中英

How to update user data in MongoDB using node.js

I have a simple express app with MongoDB connection where I can register a user. Registering and logging in and out works fine but now I'm trying to add possibility to edit user data. My code doesn't throw any errors but it doesn't update the data in database neither.

I've tried to read the MongoDB documentation and similar problems from stackoverflow. But I just can't seem to get it work.

This is my route for update:

    User.updateOne({ id: req.session.passport.user}, {
        name: req.body.name,
        email: req.body.email,
        password: req.body.password
    }, function (err, user){
        if (err) return next(err);
        User.findById(req.user._id, function(err, user) {
            if (err) return next(err);
            return res.render('user', {
            name: user.name,
            email: user.email
        });
    });
});
});

I expect it to update my database data but it just renders the user -page and nothing else happens.

EDIT. Thank you for your answers, I tried those but it still just goes through but nothing happens in database. I've also tried to make the edit work based on how I handle the registration and I actually got it to save the data but my problem with this solution is that it doesn't hash the password, it is saved as a string in my db. With registration hashing works fine. I also need to do the email validation somehow else because now it requires it to be changed every time I edit my data. Here's the code:

router.post('/update/:name', ensureAuthenticated, function(req, res, next){
  const { name, email, password, password2 } = req.body;
  let errors = [];

  //check required fields
  if (!name || !email || !password || !password2) {
    errors.push({ msg: 'Please fill in all fields' });
  }

  //check passwords match
  if (password !== password2) {
    errors.push({ msg: 'Passwords do not match' });
  }

  //check pass length
  if (password.length < 6) {
    errors.push({ msg: 'Password should be at least 6 characters' });
  }

  if (errors.length > 0) {
    res.render('update', {
      errors,
      name,
      email,
      password,
      password2
    });
  } else {
    //validation passed
    User.updateOne({ name: name, email: email, password: password })
      .then(user => {
        if (user) {
          //user exists
          errors.push({ msg: 'Email is already registered'});
          res.render('update', {
            errors,
            name,
            email,
            password,
            password2
          });
        } else {
          const updateUser = new User({
            name,
            email,
            password
          });



          //Hash password
          bcrypt.genSalt(10, (err, salt) =>
            bcrypt.hash(updateUser.password, salt, (err, hash) => {
              if (err) throw err;
              //set password to hashed
              updateUser.password = hash;
              //save user
              updateUser
                .save()
                .then(user => {
                  req.flash('success_msg', 'Info updatet, log in');
                  res.redirect('/users/login');
                })
                .catch(err => console.log(err));
          }));
        }
      });
  }
});

You need to use SET to update the document

        User.updateOne({ id: req.session.passport.user}, 
        { $set:
            {
                name: req.body.name,
                email: req.body.email,
                password: req.body.password
            }
         }, function (err, user){
        if (err) return next(err);
        User.findById(req.user._id, function(err, user) {
            if (err) return next(err);
            return res.render('user', {
            name: user.name,
            email: user.email
        });
    });
});

Use findByIdAndUpdate in this case is better

User.findByIdAndUpdate(req.session.passport.user, 
{
   $set : {
        name: req.body.name,
        email: req.body.email,
        password: req.body.password
    }
},
(err, user) => {
     // Some handle 
   }
);

Use this simple case is better.

data=user.find({ id: req.session.passport.user})
user.update({id:data.id},{name: req.body.name,email: req.body.email,password: req.body.password},
(err,user)=>{
//handle error
});

You need to use $set options with the modified property and it's value. Also be careful with the id parameter, in my case it's an ObjectId . May be in your case it is auto number or something. Anyways you need to pass _id instead of id value.

> db.users.find()
{ "_id" : ObjectId("5ceba75af8372745b2f6b861"), "name" : "allen", "email" : "email@gmail.com", "pass" : "kdsjds" }
{ "_id" : ObjectId("5ceba76cf8372745b2f6b862"), "name" : "sasmal", "email" : "sasmal@gmail.com", "pass" : "abc" }

If you go ahead with only id property the way you have mentioned in the questions, it is not gonna update the record.

> db.users.updateOne({id: ObjectId("5ceba75af8372745b2f6b861")}, { $set: {name: 'update', email: 'update@gmail.com', pass:'pass'}});
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }

it says it acknowledged but didn't able to match or modify anything.

But if you change the id to _id , you see a change in the message

> db.users.updateOne({_id: ObjectId("5ceba75af8372745b2f6b861")}, { $set: {name: 'update', email: 'update@gmail.com', pass:'pass'}});
{ "acknowledged" : true, "matchedCount" : 1, "modifiedCount" : 1 }

Now let's verify if it has changed the values in the database or not.

> db.users.find().pretty()
{
    "_id" : ObjectId("5ceba75af8372745b2f6b861"),
    "name" : "update",
    "email" : "update@gmail.com",
    "pass" : "pass"
}
{
    "_id" : ObjectId("5ceba76cf8372745b2f6b862"),
    "name" : "sasmal",
    "email" : "sasmal@gmail.com",
    "pass" : "abc"
}

NOTE: I have used mongo shell here, if you are using mongodb js driver for nodejs then everything is same.

Hope it helps!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM