I’m using angularjs to make a front end for an ecommerce site, and the only issue I have run in to so far is related to the cart implementation. I have a service that provides the Cart function, which has prototype methods to add, change, and remove items from the cart. Here’s a very basic version of it (it’s wrapped in a service declaration):
var Cart = function(){
this.items = [];
this.total_price = 0;
this.item_count = 0;
}
Cart.prototype.getItems = function(){ return this.items }
Cart.prototype.getTotal = function(){ return this.total_price }
// Add a product to the cart
Cart.prototype.add = function(product, variant, qty){
// Check if the item is already in the card and add to the quantity
// or create the line item and add it to the list
this.items.push(item)
// Update totals
this.total_price += product.price * qty;
this.item_count += qty;
console.log('Added product. total:', this.getTotal())
}
// Modify a product in the cart
Cart.prototype.change = function(product, variant, qty){
// Find the item or error
existingItem.quantity += qty;
existingItem.line_price += existingItem.price * qty;
}
// Remove an item from the cart
Cart.prototype.remove = function(item){
var index = this.items.indexOf(item);
if (index !== -1) {
this.total_price -= item.line_price;
this.item_count -= item.quantity;
this.items.splice(index, 1);
}
console.log('Removed line item. total:', this.getTotal())
}
return new Cart;
This code seems to work quite well when using it directly, but there’s a weird issue when binding it in a controller. Here’s the cart controller:
app.controller('CartCtrl', [
'$scope',
'Cart',
function($scope, Cart) {
$scope.items = Cart.getItems();
$scope.total = Cart.getTotal();
$scope.delete = function(item){ Cart.remove(item) };
}
]);
When I add products to the cart, $scope.items will update and show up in the ng-repeated list, but the $scope.total binding does nothing. I know it is actually updating, because I have put console.logs everywhere while debugging. I have also tried to call $rootScope.$apply() after the total is updated, but it just errors because it’s already running.
Does anyone have any ideas? Thanks for your help!
See if this is your issue… This line
creates a
totalproperty on $scope, and since getTotal() returns a primitive value, $scope.total is set to 0. There is no binding here, so $scope.total will not update when Cart’s total_price changes.($scope.items will update when Cart’s items changes because $scope.items is assigned a reference to the items array.)