0
votes

I'm trying to create a Cart using Angular JS Service. This service is called UserCart. The UserCart service consists of two variables, one to maintain the total cart value, other to store the items added in the cart. It additionally contains two functions to add or remove an item in the cart.

The UserCart service returns an object which has the two functions (add/remove product) and the total cart value.

In the View (html code at end), there is 'Add to Cart' button for each of the product (currently a shirt and a wine), which when clicked should call the ProductController's function 'addToCart', which should then update the UserCart's total_cart_val (And it does that as I confirmed from the console logs). However, the value is not reflecting in the HTML.

Is there any obvious issue with the code?

UserCart.js below:

(function() {
    // Get reference to the app
    var app = angular.module("jargoViewer");

    // Create the factory that share the User Cart with various controllers
    app.factory('UserCart', function(){
        var cart_items = [];
        var total_cart_val = 0;
        
        var addProductInCart = function(prodID, prodCostPerUnit, prodQuantity) {
            if((prodID in cart_items)) {
                // true if "prodID" exist in cart_items
                // Add the new prodID key element now
                prodObj = cart_items[prodID];
                prodObj.Quantity = prodObj.Quantity + prodQuantity;
            } else {
                // A product with same key already exists
                cart_items[prodID] = {
                    'Quantity' : prodQuantity,
                    'CostPerUnit' : prodCostPerUnit
                };
            }
            // Add the total newly added products cost to Total Cart Value
            total_cart_val += prodCostPerUnit * prodQuantity;
        }
        
        var removeProductInCart = function(prodID, prodQuantity) {
            if((prodID in cart_items)) {
                // true if "prodID" exist in cart_items
                // Add the new prodID key element now
                prodObj = cart_items[prodID];
                existingQuantity = prodObj.Quantity;
                if(prodQuantity > existingQuantity) {
                   alert('No more of this item exists in the cart!');
                } else {
                    prodObj.Quantity = prodObj.Quantity - prodQuantity;
                    // Add the total newly added products cost to Total Cart Value
                    total_cart_val -= prodCostPerUnit * prodQuantity;
                    if(prodObj.Quantity < 1) {
                        // No more of this product left in cart, remove from cart list
                        cart_items.splice(prodID, 1);
                    }
                }
            } else {
                // Error
                alert('No more of this item exists in the cart!');
            }
        }
        
        // Return the Interface of UserCart
        return { 
            // products_in_cart: cart_items,
            cart : {
                cart_val : total_cart_val
            },
            addProdInCart : addProductInCart,
            delProdInCart : removeProductInCart
        };
    });
}());

My ProductController.js is like this

(function() {

    var app = angular.module("jargoViewer");

    //var ProductController = function($scope) {
    var ProductController = function($scope, UserCart) {

        $scope.addToCart = function(prodID, costPerUnit, quantity) {
            UserCart.addProdInCart(prodID, costPerUnit, quantity);
        }
        
        $scope.products = [
            {
                'title' :   'First Product',
                'id'    :   100001,
                'img'   : 'product/shirt.jpg',
                'cost'  : 899,
                'sizes' : [
                    {
                        'label' :'Small'
                    },
                    {
                        'label' :'Medium'
                    }
                ]
            },
            {
                'title' : 'Second Product',
                'img'   : 'product/wine.png',
                'id'    : 100002,
                'cost'  : 3150,
                'sizes' : [
                    {
                        'label' :'Small'
                    },
                    {
                        'label' :'Large'
                    }
                ]
            }
        ];
        
        $scope.userCart = UserCart.cart;
    };
    
    app.controller("ProductController", ProductController);

}());

My View is as follows.

    <section class="big-product">
        <div class="container">
            <div class="row top30" ng-repeat="prod in products">
                <span>&nbsp</span>
                <div>
                    <div class="col-sm-4 product">
                        <!--<img src="product/shirt.jpg" alt="t-shirt" class="img-responsive">-->
                        <img src="{{prod.img}}" alt="t-shirt" class="img-responsive">
                    </div>
                    <div class="col-sm-8 info">
                        <div class="info-wrapper"  >
                            <h2>{{prod.title}}</h2>
                            <p class="lead">
                                {{prod.desc}}
                            </p>

                            <ul class="list-inline">
                                <li>
                                        <div class="dropdown">
                                            <button class="btn btn-default dropdown-toggle" type="button" id="menu1" data-toggle="dropdown">
                                                Size
                                                <span class="caret"></span>
                                            </button>
                                            <ul class="dropdown-menu" role="menu" aria-labelledby="menu1">
                                                  <li role="presentation" ng-repeat="prop in prod.sizes"><a role="menuitem" tabindex="-1" href="#">{{prop.label}}</a></li>
                                                  <!--<li role="presentation"><a role="menuitem" tabindex="-1" href="#">Medium</a></li>
                                                  <li role="presentation"><a role="menuitem" tabindex="-1" href="#">Large</a></li>-->
                                            </ul>
                                        </div>
                                </li>
                                <li>
                                        <div class="dropdown">
                                            <button class="btn btn-default dropdown-toggle" type="button" id="menu1" data-toggle="dropdown">
                                                Quantity
                                                <span class="caret"></span>
                                            </button>
                                            <ul class="dropdown-menu" role="menu" aria-labelledby="menu1">
                                                  <li role="presentation"><a role="menuitem" tabindex="-1" href="#">1</a></li>
                                                  <li role="presentation"><a role="menuitem" tabindex="-1" href="#">2</a></li>
                                                  <li role="presentation"><a role="menuitem" tabindex="-1" href="#">3</a></li>
                                            </ul>
                                        </div>

                                </li>
                                <li class="currency">
                                    {{prod.cost}}
                                </li>
                                <li class="Total Cart Value">
                                    {{userCart.cart_val}}
                                </li>
                            </ul>
                        </div>
                        <a class="btn btn-success btn-unique" ng-click = "addToCart(prod.id, prod.cost, 1)">Add to Cart<i class="icon-cart-1"></i></a>
                    </div>
                </div>
                <span>&nbsp</span>
            </div>
        </div>
    </section>
2

2 Answers

1
votes

Posting my IRC answer here:

total_cart_val is a primitive, so when you're assigning it to cart.cart_val, you're assigning the value and not a reference to the variable. Since you're updating the total_cart_val variable and not the cart.cart_val property, the changes don't reflect in the exported cart object, and, consequently, on your view.

1
votes

Try changing $scope.userCart = UserCart.cart; to:

$scope.userCart= function() {
  return UserCart.cart;
};