When the next() function of bcrypt.hash() is called, it does not activate the save method in mongoose

Attempting to hash a password using the .pre() hook:

import * as bcrypt from 'bcrypt'; // "bcrypt": "^1.0.2"
(<any>mongoose).Promise = require('bluebird');


const user_schema = new Schema({
  email: { type: String, required: true },
  password: { type: String, required: true },
})

const SALT_WORK_FACTOR = 10;

user_schema.pre('save', function (next) {
  const user = this;
  if (!user.isModified('password')) return next();
  bcrypt.hash(user.password, SALT_WORK_FACTOR, function (error, hash) {
    if (error) return next(error);
    user.password = hash;
    console.log(hash); // properly consoles the hash
    next();
  });
});

The hash value is successfully printed to the console, indicating it's being generated correctly. However, when trying to save like below:

const x = new MongoUser({
  '_id': mongoose.Types.ObjectId(),
  'email': '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="f88c9d8b8cb88c9d8b8cd69b979">[email protected]</a>',
  'password': 'testp@$$word',
})
console.log(x); // object is logged properly
x.save(function(err: any){
  console.log('callback fired'); // this does not log
  if (err) console.log(err)
});

The save() callback is never triggered.

I can confirm that removing the .pre90 hook or replacing bcrypt.hash() with next() allows saving an unhashed password successfully. So, I am certain about the schema setup and database connection.

Reason for save() not triggering?

Not a race condition as files are tested before running a separate execution script.

Answer №1

You might need to check for missing steps in your implementation. The code snippet provided below has been successfully tested using bcrypt 1.0.2, mongoose 4.8.6, and node js v7.2.0

import * as bcrypt from 'bcrypt'; 
import * as mongoose from 'mongoose'; 

const user_schema = new mongoose.Schema({
  email: { type: String, required: true },
  password: { type: String, required: true },
})

mongoose.connect('mongodb://localhost:27017/test', function(err,db){
    if (!err){
        console.log('Connected to /localhost!');
    } else{
        console.dir(err);
    }
});

const SALT_WORK_FACTOR = 10;

user_schema.pre('save', function (next) {
  const user = this;
  if (!user.isModified('password')) return next();
  bcrypt.hash(user.password, SALT_WORK_FACTOR, function (error, hash) {
    if (error) return next(error);
    user.password = hash;
    console.log(hash); // outputs the hash correctly
    next();
  });
});

var MongoUser = mongoose.model('collectionName', user_schema);

const x = new MongoUser({
  '_id': mongoose.Types.ObjectId(),
  'email': '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="304455434470445543441e535f5d">[email protected]</a>',
  'password': 'testp@$$word',
})
console.log(x); // properly logs the object
x.save(function(err: any){
  console.log('callback fired'); // callback does not fire here
  if (err) console.log(err)
});

This section displays the document created:

{ "_id" : ObjectId("58c7360e976e543af0667039"), "email" : "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="552130262115213026217b363a38">[email protected]</a>", "password" : "$2a$10$h06qq1mhTCzlP5rN6.nEW.DZSlsXzU5gsAK/lShi7NOtvG6qEvqSa", "__v" : 0 }

Output via console logs:

{ _id: 58c7360e976e543af0667039,
  email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="c8bcadbbbc88bcadbbbce6aba7a5">[email protected]</a>',
  password: 'testp@$$word' }
(node:15088) DeprecationWarning: Mongoose: mpromise (mongoose's default pro
Connected to /localhost!
$2a$10$h06qq1mhTCzlP5rN6.nEW.DZSlsXzU5gsAK/lShi7NOtvG6qEvqSa
callback fired

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Error: Unable to access the 'next' property of null within an Angular 2 Observable

Issue Found An error of type TypeError has occurred: Cannot read property 'next' of null Problematic Template Utilizing Observer.next import { NavService } from '../../providers/services/nav-service/nav-service'; @Component({ ...

I'm having trouble understanding why I can't access the properties of a class within a function that has been passed to an Angular

Currently, I have integrated HTML 5 geolocation into an Angular component: ... export class AngularComponent { ... constructor(private db: DatabaseService) {} // this function is linked to an HTML button logCoords(message, ...

An issue has occurred: Unable to locate a supporting object 'No result' of type 'string'. NgFor is only compatible with binding to Iterables like Arrays

I am attempting to utilize this code to post data from a web service. service.ts public events(id: string): Observable<Events> { ...... return this.http.post(Api.getUrl(Api.URLS.events), body, { headers: headers }) .map((re ...

Testing the React context value with React testing library- accessing the context value before the render() function is executed

In my code, there is a ModalProvider that contains an internal state managed by useState to control the visibility of the modal. I'm facing a dilemma as I prefer not to pass a value directly into the provider. While the functionality works as expecte ...

React hooks causing dynamic object to be erroneously converted into NaN values

My database retrieves data from a time series, indicating the milliseconds an object spends in various states within an hour. The format of the data is as follows: { id: mejfa24191@$kr, timestamp: 2023-07-25T12:51:24.000Z, // This field is dynamic ...

Having trouble removing an object from an array using $pull method?

I am currently facing a challenge when it comes to deleting a lesson with a specific lesson_id from the following data. { "_id" : ObjectId("5807f3f"), "title" : "Title", "lessons" : [ { "lesson_id" : ObjectId("58073"), ...

Inquiry about how TypeScript handles object property references when passed into functions

As a newcomer to TypeScript, I am exploring the creation of a range slider with dual handles using D3.js. I have developed a simple class for managing the slider objects: export class VerticalRangeSlider{ private sliderContainer: d3.Selection<SVGG ...

Unexpected Issue: Angular 12 Encounters JIT Compiler Unavailability

Lately, I've been encountering a persistent issue with an error message: Uncaught Error: JIT compiler unavailable. Ever since I upgraded from Angular version 8 to 12, whenever I run the ng build --prod --output-path = dist command and build Angular, e ...

What is the purpose of mapping through Object.keys(this) and accessing each property using this[key]?

After reviewing this method, I can't help but wonder why it uses Object.keys(this).map(key => (this as any)[key]). Is there any reason why Object.keys(this).indexOf(type) !== -1 wouldn't work just as well? /** * Checks if validation type is ...

Error: The reference to "global" is undefined and was not caught in the promise

After successfully running my project, I encountered an issue upon installing the aws-sdk package from here. Despite trying to find solutions online, I have been unable to resolve this problem. The error message I am facing is: core.js:1673 ERROR Error ...

Angular - Implementing filter functionality for an array of objects based on multiple dropdown selections

I am currently working on filtering an array of objects based on four fields from a form. These four fields can be combined for more specific filtering. The four fields consist of two dropdowns with multiple selection options and two text boxes. Upon cli ...

Unexpected date format displayed by the flat picker calendar

The expected date format is "DD-MM-YYYY" but the shown date format in the UI is "YYYY-MM-DD". Click here to view the UI image Initially, before opening the date picker, the date is displayed in the expected format as "DD-MM-YYYY". Upon opening the date p ...

Implementing Class-based Dependency Injection in Express

Incorporating Express into a TypeScript project has presented me with a particular scenario Here is my route file: ... import findAllUsersFactory from "src/factory/FindAllUsers"; routes.get("/users", findAllUsersFactory().handle); ... ...

Using Typescript, pass a Sequelize model as a property in NodeJS

Currently in the midst of a project using Node, Typescript, and Sequelize. I'm working on defining a generic controller that needs to have specific functionality: class Controller { Schema: <Sequelize-Model>; constructor(schema: <Sequel ...

How can I trigger a function after all nested subscriptions are completed in typescript/rxjs?

So I need to create a new user and then create two different entities upon success. The process looks like this. this.userRepository.saveAsNew(user).subscribe((user: User) => { user.addEntity1(Entity1).subscribe((entity1: EntityClass) => {}, ...

Can you explain the parameters accepted by the Model.prototype.save() function in mongoose?

I am confused about the save function's callback in Mongoose. The documentation only mentions that it is an optional callback without providing any specific information on the parameters it accepts. This lack of clarity has left me wondering why Mongo ...

Using Mongoose to populate fields after a find() query

Just getting started with mongo and node js, here is what I am working on: The task of the API is to check if there is an existing entry in the database based on the query. (a) If there is no existing document, create a new one, fill it, and send it to ...

The Angular Material side navigation module is not being acknowledged

Currently, I am utilizing Angular version 9.1.11 in conjunction with Angular Material version 9.2.4. The issue arises when attempting to import the MaterialSidenavModule, which is required for utilizing components like mat-sidenav-container. Below is a sn ...

Save user sessions in a database using node.js, express, and mongoose-auth

I have a question about authentication and sessions in node.js. So, I've set up authentication using express.js and mongoose-auth with mongodb: app.use(express.cookieParser()); app.use(express.session({ secret: 'esoognom'})); app.use(auth. ...

Issue with Vue @Watch not properly recognizing changes in a boolean value

I'm currently experimenting with watch functions in vue-ts. I have configured a watch function that is supposed to trigger whenever a Boolean variable's value changes, but for some reason, it's not triggering at all and I'm unable to de ...