user.save (), похоже, не сохраняет конкретное поле, которое я добавляю пользователю

#javascript #node.js #mongodb #mongoose

Вопрос:

Если я использую await user.save() приведенный ниже код, он, кажется, застревает, но если я использую его без ожидания, он, кажется, движется вперед, и в ответе passwordResetToken отображается.. Однако в базе данных по какой-то причине остальные поля сохраняются, но passwordResetToken просто не сохраняются.

Я совершенно не понимаю, в чем может быть причина.. Любое указание на то, что мне следует искать, помогло бы.

 exports.forgotPassword = async function(req, res, next) {

  // 1. Get user based on POST email
  const user = await User.findOne({ email: req.body.email });

  // 2. Generate random token
  user.passwordResetToken = "123456";

  await user.save({ validateBeforeSave: false });

  // 3. Send it back as an email

  //4. Send Response
  res.status(200).json({
    status: "success",
    data: {
      user: user,
    },
  });
};

 

это и есть ответ

 
{
    "status": "success",
    "data": {
        "user": {
            "role": "user",
            "_id": "6116aeb70aae0f7c7d8800bc",
            "name": "Jane Doe",
            "email": "jane@doe.com",
            "__v": 0,
            "passwordResetToken": "123456"
        }
    }
}

 

Однако passwordResetToken он по-прежнему не сохраняет его в базе данных, хотя остальная его часть сохраняется.. У меня действительно есть поле passwordResetToken as a в мангусте.Схема

Я не добавил этот раздел ниже к своему вопросу ранее, поэтому я добавляю это, чтобы помочь понять, в чем может заключаться проблема..

Это тот самый userModels.js

 const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, "Name is required"],
  },
  email: {
    type: String,
    required: [true, "Email is required"],
    validate: [validator.isEmail, "Please provide valid email"],
    unique: true,
  },
  role: {
    type: String,
    enum: ["admin", "lead-guide", "guide", "user"],
    default: "user",
  },
  photo: String,
  password: {
    type: String,
    minlength: 8,
    required: [true, "Password is required"],
    select: false,
  },
  passwordConfirm: {
    type: String,
    validate: {
      validator: function(el) {
        return el === this.password;
      },
      message:
        "Password confirmation does not match with Password. Please try again",
    },
  },
  passwordChangedAt: Date,
  passwordResetToken: String,
  passwordResetExpires: Date,
});

 

и вот строка из userRouter.js для этого маршрута..

 router.route("/forgotPassword").post(authController.forgotPassword);

 

Ответ №1:

Может быть, вы можете попробовать с

 let user = await User.findOne({ email: req.body.email });

  // 2. Generate random token
  user.passwordResetToken = "123456";

  user = await user.save();
 

или вы можете использовать

 const user = await User.findOneAndUpdate({email:req.body.email},{$set:{passwordResetToken:'123456'},{new:true})
 

новое: true вернет обновленные данные.

Комментарии:

1. На самом деле мне нужно запустить отдельный экземпляр функции UserSchema.methods.createResetPasswordToken для пользователя, а затем user.save().. поэтому поиск и обновление-это не вариант..

2. вы пробовали сохранить ответ user.save() в пользовательской переменной?

Ответ №2:

Убедитесь, что файл модели содержит поле passwordResetToken. В противном случае это будет проигнорировано.

Комментарии:

1. У меня есть поле в файле модели..:-).. и вот почему это так запутанно.. Я, кажется, не могу понять, в чем еще может быть проблема..

2. @AlimBolar Не могли бы вы добавить код файла модели в свой вопрос? Код, который вы опубликовали до сих пор, выглядит идеально.

3. Я обновил вопрос с моделями файла и маршруты деталей, так же.. не могли бы вы помочь мне выяснить, почему await user.save() сделал бы код не работает (он не идет дальше), а просто user.save() хотя бы идет вперед, хотя это и не спасает на базе… может быть, что бы дать нам ключ к пониманию, в чем именно заключается ошибка..

4. в этой части мы также обновили функцию ForgotPassword.. await user.save({ validateBeforeSave: false }); … опция validateBeforeSave ранее отсутствовала .. но, честно говоря, это, похоже, ничего не делает, так как все проверки, похоже, в любом случае выполняются при сохранении..

5. userSchema.pre("save", function(next) { if (!this.isModified("password") || this.isNew) return next(); Я понял, что совершаю эту глупую ошибку.. Я забыл восклицательный знак раньше this.isModified … извините за беспокойство … и спасибо за ваши усилия..

Ответ №3:

Интересно, если проблема связана с HTTP-запросом, вы можете захотеть, чтобы запрос http.post не http.put для вашего опубликованного вопроса.

Комментарии:

1. обновили запрос с подробной информацией о модели и спецификациях маршрута..

Ответ №4:

Я не уверен, найдете ли вы свою собственную ошибку, следует ли вам удалить вопрос или обновить его ответом. Но я просто отвечу на него здесь, просто чтобы кто-то, кто совершает ту же ошибку, что и я, мог знать, что может пойти не так.

Когда кажется, что что-то не сохраняется или когда вы await используете метод save() и он заходит в тупик, скорее всего, это промежуточное программное обеспечение перед сохранением..

Это может быть не очевидно для таких, как я, и вы можете в конечном итоге попытаться исправить и заменить свой «идеальный» код, в то время как ошибка кроется в другом месте.. Итак, 2 вещи, которые нужно проверить, если что-то не сохраняется, и если ожидание создает бесконечный ответ)

1. Проверьте, правильно ли настроено промежуточное программное обеспечение для предварительного сохранения

2. Проверьте, заканчивается ли промежуточное программное обеспечение следующим()

В моем случае это было так.. В приведенном ниже коде я пропустил ! до this.isModified("password") и поэтому во время тестирования ответ показал бы мне правильный объект, но он никогда не был бы сохранен при перемещении промежуточного программного обеспечения перед сохранением next() .

Проблема await взаимоблокировки заключалась в том, что я не завершил промежуточное программное обеспечение с помощью этого next() метода.

это ошибочный код

 userSchema.pre("save", function(next) {
  if (this.isModified("password") || this.isNew) return next();

  this.passwordChangedAt = Date.now() - 1000;
});
 

это правильный код

 userSchema.pre("save", function(next) {
  if (!this.isModified("password") || this.isNew) return next();

  this.passwordChangedAt = Date.now() - 1000;
next();
});
 

В любом случае, я надеюсь, что это сэкономит кому-то некоторое время во время отладки их кода.