Search code examples
mongodbexpressmongoose

Database query within static function causes the program to wait indefinitely


I'm following a youtube tutorial (https://www.youtube.com/watch?v=mjZIv4ey0ps&list=PL4cUxeGkcC9g8OhpOZxNdhXggFz2lOuCT&index=3&t=597s) for making a login and authorization system and provided the link for the part I'm stuck on. you see when I invoke this.findOne({}) function from within a static method I created in the Schema file, the program starts waiting indefinitely, and no further code runs. The code for the model is,

const mongoose = require('mongoose')
const Schema = mongoose.Schema
const bcrypt = require('bcrypt')

const userSchema = new Schema({
    email: {
        type: String,
        required: true,
        unique: true,
    },
    password: {
        type: String,
        required: true
    }
})
userSchema.statics.signup = async (email, password) => {
    console.log("Static Method Triggered")
    const exists = await this.findOne({ email })
    console.log("Verifying existence")

    if (exists) {
        throw Error("Email is already in use")
    }
    console.log("Existence verified")

    const salt = await bcrypt.genSalt(5)
    const hash = await bcrypt.hash(password, salt)
    console.log(hash)
    const user = await this.create({ email: email, password: hash })
    console.log("End of function")
    return user
}

module.exports = mongoose.model('User', userSchema) 

As you can see, I have log statements to see how far the program gets. I get the "Static Method Triggered" statement in the console, but not the "Verifying existence" statement or any subsequent statements. This means that the program is waiting indefinitely at the const exists = await this.fineOne({email}) line.

I have tried using find instead of findOne, same result. Other queries to the database work so it's not a problem with mongodb Atlas. Only custom functions (static methods) are having this problem. I tried editing the statement to

findOne({email: email})

and it's still the same result. Removing these statements entirely causes the salt and hash statements to run and the hash to be logged, but then the program starts to wait indefinitely again at the

const user = await this.create({email: email, password: hash})

line. If I do console.log(this), it returns empty curly brackets {}. What am I doing wrong? Did I miss a step somewhere in the tutorial?


Solution

  • The this keyword works different in arrow functions () => {}. So use a regular function function(){} instead.

    Updated code:

    userSchema.statics.signup = async function(email, password) {
        console.log("Static Method Triggered")
        const exists = await this.findOne({ email })
        console.log("Verifying existence")
    
        if (exists) {
            throw Error("Email is already in use")
        }
        console.log("Existence verified")
    
        const salt = await bcrypt.genSalt(5)
        const hash = await bcrypt.hash(password, salt)
        console.log(hash)
        const user = await this.create({ email: email, password: hash })
        console.log("End of function")
        return user
    }
    

    Hope this helps