Невозможно присвоить значение из promise свойству класса

#javascript #node.js #postgresql #express

#javascript #node.js #postgresql #выразить

Вопрос:

Я пытаюсь создать веб-приложение с node.js , express.js и postgres SQL тоже. Пока я создал User класс, который выглядит следующим образом:

 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 класс имеет register hashPassword и getSignedJwtToken методы, которые работают должным образом
Проблема заключается в:

  • register Функция возвращает слишком много данных, и мне нужно только то, что отмечено на скриншоте ниже, например _user_id , firstname , lastname и т.д. Без fields свойства из полезной нагрузки введите описание изображения здесь
  • Я хотел бы сохранить эти данные, отмеченные выше, в свойствах User класса, таких как this._user_id = user.rows[0]._user_id

Но каждый раз, когда я пытаюсь изменить register функцию, что-то вроде этого:

 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]
    }
  

Или это

 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]
    }
  

Или просто попробуйте использовать then для user переменной, подобной этой

 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
    }
  

Происходит одно из следующих событий:

  • Сервер выдает ошибку 400
  • Аутентификация работает, но ответ от сервера не возвращает пользовательских данных
  • Аутентификация не работает, но ответ от сервера содержит пользовательские данные

Итак, перейдем к делу, как я могу получить определенные данные из user переменной и как сохранить эти данные в User свойствах класса.

Ниже приведен код из UserController при импорте и вызове register метода

 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 
        })
    }
}
  

Комментарии:

1. Похоже, основная проблема здесь в том, что вы не await обрабатываете запрос.