0

Im working in express framework and sequelize orm, and i have following controller for the basket of devices:

const {Basket, BasketDevice, Device} = require('../models/models')
const ApiError = require('../error/ApiError')

class BasketControlller {
    static deviceId;
    static quantity;
    static basket;
    static basketDevice;


    async getRequestValues(req){
        const {deviceId} = req.body
        let {quantity} = req.body
        this.deviceId = deviceId
        this.quantity = quantity
        
        this.basket = await Basket.findOne({
            where: {userId: req.user.id},
        })
        this.basketDevice = await BasketDevice.findOne({
            where: {deviceId: deviceId, basketId: basket.id},
        })
        this.BasketControlller.deviceId = deviceId
        return this
    }

    async add(req, res, next){
        this.getRequestValues(req)

        if(this.basketDevice){
            if(!this.quantity){
                this.quantity = 1
            }

            this.basketDevice = await BasketDevice.update(
                {quantity: this.basketDevice.quantity + Number(this.quantity)}, 
                {where: {deviceId: this.deviceId, basketId: this.basket.id}
            })
        }
        else{
            this.basketDevice = await BasketDevice.create({deviceId: this.deviceId, basketId: this.basket.id})
        }
        
        return res.json({message: `Successfully added ${this.quantity} units of goods`})
    }

    async getOne(req, res, next){
        const basket = await Basket.findOne({
            where: {userId: req.user.id},
            include: {
                model: BasketDevice,
                include: {
                    model: Device
                },
                attributes: ['id', 'deviceId', 'basketId', 'quantity'],
            }, 
        })    

        return res.json(basket)
    }

    async delete(req, res, next){
        this.getRequestValues()

        if(this.basketDevice){
            if(!this.quantity){
                this.quantity = 1
            }
            else if(this.basketDevice.quantity == 1){
                this.basketDevice = await BasketDevice.destroy({
                    where: {
                        deviceId: this.deviceId,
                    }
                })
                return res.json({message: 'The product was successfully deleted'})
            }
            this.basketDevice = await BasketDevice.update(
                {quantity: this.basketDevice.quantity - Number(this.quantity)}, 
                {where: {deviceId: this.deviceId, basketId: this.basket.id}
            })
        }
        else{
            return next(ApiError.badRequest('The product in the basket is already missing'))
        }
        
        return res.json({message: `Successful deleted ${quantity} units of goods`})
    }
}

module.exports = new BasketControlller()

In a add and delete methods i do the same operations: parsing request. I decided to do bring it all into the static method and working through static fields of class, but i get following error:

D:\JavaScript\testNodeReact\server\controllers\basketController.js:30
    this.getRequestValues(req)
         ^

TypeError: Cannot read properties of undefined (reading 'getRequestValues')
    at add (D:\JavaScript\testNodeReact\server\controllers\basketController.js:30:14)
    at Layer.handle [as handle_request] 
(D:\JavaScript\testNodeReact\server\node_modules\express\lib\router\layer.js:95:5)

I just followed DRY principe, but i dont know how make it more correct. Thank you in advance.

rjunovskii
  • 23
  • 5
  • 2
    IMO using `this.deviceId` doesn't make sense since it's supposed to be a static property. – evolutionxbox Jul 01 '22 at 14:49
  • The fastest-gun answers didn't have the time to explain why. Before marking one correct, see if you motivate a contest for the most cogent explanation. Bonus points for explaining what this means *inside* the static method. – danh Jul 01 '22 at 14:57
  • `deviceId`, `quantity`, `basket` and `basketDevice` should not be declared as `static`, **or** all of your methods should be declared as `static` as well. And there's no `this.BasketControlller`. – Bergi Jul 01 '22 at 16:08
  • The way your code is written with instance properties and state, you will need to instantiate a `new BasketController` **per request**. Do not export a single instance, do export the class itself, and use it accordingly. The (probably better) alternative would be not to use instance properties to store state, and use only local variables in the methods instead. `getRequestValues` will then need to return an object. – Bergi Jul 01 '22 at 16:09
  • Also, you might want to consider [not using `class` at all](https://stackoverflow.com/q/29893591/1048572) – Bergi Jul 01 '22 at 16:11

2 Answers2

0

Try:

BasketControlller.getRequestValues(req)

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/static

Hammerbot
  • 15,696
  • 9
  • 61
  • 103
0

You have to call

BasketControlller.anyStaticMemberOfTheClass

Mohammad Faisal
  • 2,265
  • 1
  • 10
  • 16