Search code examples
node.jsexpressmongoosemongoose-schema

Why code is not working when ı dont have async in pre middleware?


    curUser.password = newPassword;
  curUser.passwordConfirm = passwordConfirm;
  await curUser.save();

I have this code to be executed in this function :

    exports.updatePassword = catchAsync(async (req, res, next) => {
  // 1-) Get user from the collection
  const { currentPassword, newPassword, passwordConfirm } = req.body;

  const curUser = await User.findById(req.user.id).select('+password');

  if (!curUser) {
    return next(new AppError('Token is invalid !', 404));
  }

  // 2-) Check if posted current password is correct
  if (!(await curUser.correctPassword(curUser.password, currentPassword))) {
    return next(new AppError('Password is incorrect !', 401));
  }

  curUser.password = newPassword;
  curUser.passwordConfirm = passwordConfirm;
  await curUser.save();
  //findByIdAndUpdate yerine save ederek kullanmamızın sebebi oluşturmuş olduğumuz pre middlewareleri ile validatorların update işleminde
  //çalışmayacak olması

  //3-) Log user in, send JWT
  createTokenAndSend(200, res, curUser._id);
});

And above that ı have one middleware in userModel to create passwordChangedAt in database when user updated his password :

userSchema.pre('save', async function(next) {
  if (!this.isModified('password') || this.isNew) return next();
  //Eğer yeniyse bu fonksiyonu çalıştırmamasını ve direk diğer middleware'e geçmesini belirttik

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

So, problem is why this middleware method is has to be async. When ı remove the 'asycn' before that pre middleware funcitonı got an error in postman. Actually is not error just posmtan cant get any response like that : This is the image of that

So, why am ı getting that problem when ı remove the async from that pre middleware ?


Solution

  • Your middleware needs to either call the next function or return a promise (that eventually resolves), otherwise it will never be considered "done", leading to your never ending request. (https://mongoosejs.com/docs/middleware.html)

    If you look at your middleware, it shows that you are not calling next if !this.isModified('password') || this.isNew evaluates to false. Therefore, if the middleware does not return a promise, it will never be considered done.

    Using async converts your function to return a promise, thereby obeying the contract of the middleware.

    Alternatively, try removing async and add next(); to the end of the function after updating passwordChangedAt.