Taras Danylchenko
Taras Danylchenko

Reputation: 347

AngularJS Binding Data

So i have a productList and cart where i store products, when i add product to cart(localStorage), products count must async refreshed, but it refreshed only with refreshing a page (this is about goodsInCart). Maybe it needed to adding EventListener? Please tell me where i was wrong.

products.html

<div ng-controller="ProductController">
    <div class="container">
        <h1 class="page-header">Product List</h1>
         <div class="small-cart">
            <a href="#!/cart">
              <span class="amount">{{goodsInCart}}</span>
              <img class="cart" src="./images/cart_2.png">
            </a>
          </div>
         <div class="row">
            <div class="item col-sm-6 col-md-4 col-lg-3" ng-repeat="product in products">
                <h3>{{product.title}}</h3>
                <img class="product-photo" src="{{product.photoURL}}" alt="">
                <p>{{product.price}} UAH</p>
                <button class="btn btn-cart" ng-click="addToCart(product)">Add to cart</button>
            </div> 
        </div>
     </div>
</div>

ProductService.js

testApp.factory('CartProduct', function(localStorageService) {
  var cartProducts = [];
  var goodsInCart = 0;

  function init() {
    checkCartChanged();
    if (localStorageService.get('cart-products')!=null) {
      cartProducts = localStorageService.get('cart-products');
      calcGoodsInCart();
    }
  }

  init();

  function getAll() {
    return cartProducts;
  }

  function addToCart(product) {
      cartProducts.push({product : product,amount : 1});
      refresh();
    }

  function store(key,value) {
     localStorageService.set(key, value);
  }

  function calcGoodsInCart() {
     var temp = 0;
     temp = cartProducts.length;
     goodsInCart = temp;
     return goodsInCart;
  }

  function getStorageItem(key) {
    for (var i = 0; i < localStorageService.length(); i++) {
        return localStorageService.get(key);
    }
    return null;
  }


  function checkCartChanged() {
    const storedGoods = getStorageItem('goods');
    cartProducts = storedGoods ? storedGoods : [];
    calcGoodsInCart();
  }  

  function refresh () {
    store("goods",cartProducts);
    calcGoodsInCart();
  }

  function deleteAllProducts() {
    this.localStorageService.clear('goods');
  }

  function findCartItem(product){
    for(let i =0; i < cartProducts.length;i++){
      if (product.id == cartProducts[i].product.id) {
        return i;
      }
    return -1;
    }
  }

  function deleteProduct(product){
    let index = findCartItem(product);
    if (index < 0) {
      return;
    }
    cartProducts.splice(index, 1);
    refresh();
  }

  function deleteAllProducts() {
    localStorageService.clear('goods');
  }

  return {
    addToCart: addToCart,
    getAll: getAll,
    calcGoodsInCart:calcGoodsInCart,
    getStorageItem:getStorageItem,
    deleteProduct:deleteProduct,

    goodsInCart:goodsInCart
  };
});

ProductController.js

testApp.controller('ProductController',function ProductController($scope,$http,CartProduct) {
    $scope.products = [
       { id:1, title: 'Margarita', photoURL:'...',price:260},
       { id:2, title: 'Margarita', photoURL:'...', price:240},
       { id:3, title: 'Margarita', photoURL:'...', price:200},
       { id:4, title: 'Margarita', photoURL:'...', price:190}
    ]; 

    $scope.addToCart = function (product) {
        CartProduct.addToCart(product);
    }

    $scope.goodsInCart = CartProduct.goodsInCart;

});

Upvotes: 0

Views: 71

Answers (1)

Rodrigo Ferreira
Rodrigo Ferreira

Reputation: 1091

There are two problems with your approach, the first one is that you're saving only the first value of goodsInCart in your controller in the line $scope.goodsInCart = CartProduct.goodsInCart;.

The second one is that you're exposing only values instead of references.

The solution would be to wrap goodsInCart inside an object and provide its reference instead.

testApp.factory('CartProduct', function(localStorageService) {
  var cartProducts = [];
  var sharedObj = {
    goodsInCart: 0
  }

  ...

  function calcGoodsInCart() {
    var temp = 0;
    temp = cartProducts.length;
    sharedObj.goodsInCart = temp;
    return temp;
  }

  ...

  return {
    addToCart: addToCart,
    getAll: getAll,
    calcGoodsInCart:calcGoodsInCart,
    getStorageItem:getStorageItem,
    deleteProduct:deleteProduct,

    sharedObj:sharedObj
  };

Note: Be careful when trying to share an object, if you change the reference of sharedObj inside your factory, any of the controllers that use it will lose the reference. That's why you should modify only the attributes of the shared obj.

Then you can use the provided object in your controller like this:

$scope.sharedObj = CartProduct.sharedObj;

Hope it helps!

Upvotes: 1

Related Questions