Unable to assign value from promise to property of class

Viewed 54

I'm trying to build web app with node.js, express.js and postgres SQL as well. So far I created User class which looks like below:

const pool = require('./../db')
const bcrypt = require('bcryptjs')
const jwt = require('jsonwebtoken')

class User {

  constructor() { }

    async register(firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd) {
        const user = pool.query(
            'INSERT INTO users ( \
                firstName, \
                lastName, \
                email, \
                pass, \
                companyName, \
                country, \
                lang, \
                subscriptionEnd, \
                freeTrialEnd \
            ) \
            VALUES \
                ($1, $2, $3, $4, $5, $6, $7, $8, $9) \
            RETURNING *', 
            [firstName, lastName, email, await this.hashPassword(pass), companyName, country, lang, subscriptionEnd, freeTrialEnd]
        )
        return user
    }

    async hashPassword(pass) {
        const salt = await bcrypt.genSalt(10)
        const password = await bcrypt.hash(pass, salt)
        return password
    }

    getSignedJwtToken(id) {
        return jwt.sign({ id: id }, "ulta-secret-string-that-has-to-be-changed-later-in-the-config", {
            expiresIn: "30d" // change later to config as well
        })
    }
}

module.exports = User

User class has register, hashPassword and getSignedJwtToken methods which work as expected The problem is:

  • The register function returns too much data and I only need what is marked on screenshot below like _user_id, firstname, lastname etc without fields property from payload enter image description here
  • I would like to save these data marked above in the User class properties like this._user_id = user.rows[0]._user_id

But every time I try to change register function so something like this:

async register(firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd) {
        const user = pool.query(
            'INSERT INTO users ( \
                firstName, \
                lastName, \
                email, \
                pass, \
                companyName, \
                country, \
                lang, \
                subscriptionEnd, \
                freeTrialEnd \
            ) \
            VALUES \
                ($1, $2, $3, $4, $5, $6, $7, $8, $9) \
            RETURNING *', 
            [firstName, lastName, email, await this.hashPassword(pass), companyName, country, lang, subscriptionEnd, freeTrialEnd]
        )
        return user.rows[0]
    }

Or this

async register(firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd) {
        const user = pool.query(
            'INSERT INTO users ( \
                firstName, \
                lastName, \
                email, \
                pass, \
                companyName, \
                country, \
                lang, \
                subscriptionEnd, \
                freeTrialEnd \
            ) \
            VALUES \
                ($1, $2, $3, $4, $5, $6, $7, $8, $9) \
            RETURNING *', 
            [firstName, lastName, email, await this.hashPassword(pass), companyName, country, lang, subscriptionEnd, freeTrialEnd]
        )
        return assignedToUserClass(user)
    }

    assignedToUserClass(userData) {
        this._user_id = userData._user_id
        this.firstName = userData.firstname
        this.lastName = userData.lastname
        this.email = userData.email
        this.companyName = userData.companyname
        this.country = userData.country
        this.lang = userData.lang
        this.subscriptionEnd = userData.subscriptionend
        this.freeTrialEnd = userData.freetrialend
        return userData.rows[0]
    }

Or just try to use then on user variable like this

async register(firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd) {
        let data
        const user = pool.query(
            'INSERT INTO users ( \
                firstName, \
                lastName, \
                email, \
                pass, \
                companyName, \
                country, \
                lang, \
                subscriptionEnd, \
                freeTrialEnd \
            ) \
            VALUES \
                ($1, $2, $3, $4, $5, $6, $7, $8, $9) \
            RETURNING *', 
            [firstName, lastName, email, await this.hashPassword(pass), companyName, country, lang, subscriptionEnd, freeTrialEnd]
        )
        .then(res => {
            res = res.rows[0]
            this._user_id = res._user_id
            this.firstName = res.firstname
            this.lastName = res.lastname
            this.email = res.email
            this.companyName = res.companyname
            this.country = res.country
            this.lang = res.lang
            this.subscriptionEnd = res.subscriptionend
            this.freeTrialEnd = res.freetrialend
            data = res
        })
        return data
    }

Or when I try to return this

async register(firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd) {
        let self = this
        const user = pool.query(
            'INSERT INTO users ( \
                firstName, \
                lastName, \
                email, \
                pass, \
                companyName, \
                country, \
                lang, \
                subscriptionEnd, \
                freeTrialEnd \
            ) \
            VALUES \
                ($1, $2, $3, $4, $5, $6, $7, $8, $9) \
            RETURNING *', 
            [firstName, lastName, email, await this.hashPassword(pass), companyName, country, lang, subscriptionEnd, freeTrialEnd]
        )
        .then(res => {
            res = res.rows[0]
            self._user_id = res._user_id
            self.firstName = res.firstname
            self.lastName = res.lastname
            self.email = res.email
            self.companyName = res.companyname
            self.country = res.country
            self.lang = res.lang
            self.subscriptionEnd = res.subscriptionend
            self.freeTrialEnd = res.freetrialend
        })
        return this
    }

One of the following happens:

  • Server throwns an error 400
  • Authentication works but response from server returns no user data
  • Authentication not works but response from server contains user data

So cutting to the chase how can I get certain data from user variable and how to save this data to User class properties.

Below is code from userController when I import and call register method

const User = require('./../models/user')

exports.register = async (req, res) => {
    try {
        const { firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd } = req.body
        const user = new User()
        const newUser = await user.register(firstName, lastName, email, pass, companyName, country, lang, subscriptionEnd, freeTrialEnd)
        const token = user.getSignedJwtToken(newUser.rows[0]._user_id)

        res.status(200).json({
            status: 'ok',
            user: newUser,
            token: token
        })
    } catch (e) {
        res.status(400).json({
            status: 'failed',
            message: e 
        })
    }
}
0 Answers
Related