Paweenwat Maneechai
Paweenwat Maneechai

Reputation: 357

Javascript - Convert function that have a least two callbacks style to promise style

I moving from callback style to promise style to avoid the callback that made me hard to maintain the code. I use util module to import and convert the callback function with util.promisify(), but the question is if the function have at least two callbacks. How the function will return in promise form, then how can I manage the code to get the promise from two conditional callback.

Callback style example.

loginAccount = async ({email,password},success,unsuccess) => {
    this.db.query(`SELECT id, password FROM account WHERE email = ?`,[email],(err,result)=>{
      if (err) throw err
      if (result.length === 0) {
        unsuccess("ไม่มีบัญชีนี้อยู่ในระบบ ตรวจสอบอีเมลว่าถูกต้องหรือไม่")
        return
      }
      const account = result[0]
      bcrypt.compare(password,account.password,(error,response)=>{
        if (err) throw err
        if (!(response)) {
          unsuccess("รหัสผ่านไม่ถูกต้อง")
          return
        }
        this.getUser(account.id,success,unsuccess)
      })
    })
  }

I can convert into promise form like this, but I don't know how to return success or unsuccess.

  loginAccount = async ({email,password},success,unsuccess) => {
    const result = await this.query(`SELECT id, password FROM account WHERE email = ?`,email)
    if (result.length > 0) {
      const account = result[0]
      const response = await this.compareHash(password,account.password)
      if (response) {
        return this.getUser(account.id)
      }
      else {
        // return unsuccess
        // Wrong password
      }
    }
    else {
      // return unsuccess
      // No account in the database
    }
}



another example of callback style and promise style.

registerAccount = async ({firstname,lastname,email,password},success,unsuccess) => {
    this.hasAccount(email,(exist)=>{
      if (exist === true) {
        unsuccess("บัญชีนี้เคยลงทะเบียนไว้แล้ว")
        return
      }
      bcrypt.hash(password,this.saltRound,(err,hash)=>{
        if (err) throw err
        this.db.query(`INSERT INTO account (firstname,lastname,email,password) VALUES(?,?,?,?); 
                      SET @user_id = LAST_INSERT_ID(); INSERT IGNORE INTO role (id) VALUES (@user_id);
                      INSERT INTO student_data (id) VALUES (@user_id); 
                      INSERT INTO profile_image (id) VALUES (@user_id);`,
        [firstname,lastname,email,hash],
        (err,result)=>{
          if (err) throw err
          success()
        })
      })
    })
  }
registerAccount = async ({firstname,lastname,email,password},success,unsuccess) => {
    const exist = await this.hasAccount(email)
    if (exist) {
      // unsuccess function return
      // account is already exists.
      return
    }
    const hash = await this.generateHash(password,this.saltRound)
    const registerQuery = `INSERT INTO account (firstname,lastname,email,password) VALUES(?,?,?,?); 
                          SET @user_id = LAST_INSERT_ID(); INSERT IGNORE INTO role (id) VALUES (@user_id);
                          INSERT INTO student_data (id) VALUES (@user_id); 
                          INSERT INTO profile_image (id) VALUES (@user_id);`
    const result = await this.query(registerQuery,[firstname,lastname,email,hash])
    
    // success function
  }

this.query, this.compareHash and this.generateHash, I'm using the library called util.promisify() to get promise function.

this.query come from mysql query function, this.compareHash and this.generateHash both are come from bcrypt.compare and brcypt.hash

this.compareHash will compare the hash by using plain password and hash password.

this.generataHash will generate the hash by using plain password and salt round to return a hash password.

this.getUser function.

  getUser = async (id) => {
    const result = await this.query(`SELECT * FROM profile_view WHERE id = ?`,id)
    return result[0]
  }

Upvotes: 0

Views: 70

Answers (0)

Related Questions