Search code examples
javascripteventsbindinges6-classdecoupling

Access a Class property within the static method by "this" keyword


Hey guys i started reading about Javascript ES6 classes so was trying out something

Here is my ProductItem class which render each product

class ProductItem {
  constructor(product) {
    this.product = product;
  }
  addToCart() {
    console.log("adding product to cart", this.product);
    ShoppingCart.addProduct(this.product);
  }
  render() {
    const prodEl = document.createElement("li");
    prodEl.className = "product-item";
    prodEl.innerHTML = `
      <div>
        <img src="${this.product.imageUrl}" alt="${this.product.title}" >
        <div class="product-item__content">
          <h2>${this.product.title}</h2>
          <h3>\$${this.product.price}</h3>
          <p>${this.product.description}</p>
          <button>Add to Cart</button>
        </div>
      </div>
    `;
    const addCardButton = prodEl.querySelector("button");
    addCardButton.addEventListener("click", this.addToCart.bind(this));
    return prodEl;
  }
}

In another class we loop and instantiate this class like

for (const prod of this.products) {
      const productItem = new ProductItem(prod);
      const prodEl = productItem.render();
      prodList.append(prodEl);
    }

So now the problem is that i made another class called "ShoppingCart" to add products to cart when i click on button so thats like

class ShoppingCart {
  constructor(items){
    console.log(this)
    this.items=items
  }
  static addProduct(product) {
    console.log(this);
    this.items.push(product);
    this.totalOutput = `<h2>Total Amount: ${1}</h2>`;
  }


}

as i read static method can be called without Instantiating class so what i did was when i click on button in my "ProductItem" class i called a fn() and then u can see in that function what i did was

addToCart() {
    console.log("adding product to cart", this.product);
    ShoppingCart.addProduct(this.product);
  }

But this gives me error that

Uncaught TypeError: Cannot read property 'push' of undefined

and also when i console "this" in addProduct i see something weird as output

> class ShoppingCart {   constructor(items){
>     console.log(this)
>     this.items=items   }   static addProduct(product) {
>     console.log(this);
>     this.items.push(product);
>     this.totalOutput = `<h2>Tot…........

Solution

  • The problem is that this.items.push(product) tries to push a product into this.items, however you never initialize this.items so its value is undefined. The constructor is only executed when you create a new instances of a class, but not for the class itself.

    To solve the problem you have to define a static items property on ShoppingCart:

    class ShoppingCart {
      static items = [];
    
      static addProduct(product) {
        this.items.push(product);
        this.totalOutput = `<h2>Total Amount: ${1}</h2>`;
      }
    }