Tom Brunoli
Tom Brunoli

Reputation: 3466

Angular binding wont update

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!

Upvotes: 2

Views: 674

Answers (1)

Mark Rajcok
Mark Rajcok

Reputation: 364677

See if this is your issue... This line

$scope.total = Cart.getTotal();

creates a total property 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.)

Upvotes: 3

Related Questions