0

I'm building an application that allows the user to add food items to a basket based on their size (individual, medium large) which are different prices. The problem I am facing is that when I add more than one (using ng-click), the prices for all items in the array are also changing. I can't get my head around it!

When a user selects a product (pizza for example) the variable selectedProduct is changed to the selected product.

This is my code to add to the basket:

$scope.addToCart = function(key, size, price) {


        //Add selected size and price

        //Add 'extra' for selected price and size
        $scope.selectedProduct.extra = {};
        $scope.selectedProduct.extra = {
            //price is a float
            price: price,
            //$scope.productSizes is a single array that
            //changes int values to sizes (1 => individual, 2 => medium ...)
            size: $scope.productSizes[size],
            //size is the int value of the size
            sizeInt: size
        };

        $scope.cart.push($scope.selectedProduct);
};

When I add an item (size = 1) to the array via push I get this in the extra key within the console

0 Object
    extra: Object
      price: "1.99"
      size: "Individual"
      sizeInt: 1

When I add a second item (size = 3) my array changes both the first and second item in the array

0: Object
    extra: Object
      price: "6.5"
      size: "Large"
      sizeInt: 3
1: Object
    extra: Object
      price: "6.5"
      size: "Large"
      sizeInt: 3

3 Answers 3

6

It is happening because you are pushing reference to the $scope.selectedProduct into array.

Short example of references:

var a = {'key': 'foo'};
var b = a;
b['key'] = 'bar';
console.log(a['key']);   // initially it was 'foo'

I recommend you to create a new object on addToCart and push it into array:

$scope.addToCart = function(key, size, price) {
    $scope.cart.push({
        extra: {
            price: price,
            size: $scope.productSizes[size],
            sizeInt: size
        }
    });
};

Or you can copy $scope.selectedProduct on addToCart with angular.copy():

$scope.addToCart = function(key, size, price) {
    var product = angular.copy($scope.selectedProduct);
    product.extra = {
        price: price,
        size: $scope.productSizes[size],
        sizeInt: size
    };
    $scope.cart.push(product);
};
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much, I couldn't figure that out! You fixed my problem :)
@JakeBown glad to help
0

I think you're unnecessarily binding selectedProduct to $scope.

You continuously update and push $scope.selectedProduct to the array; and see this result because you are passing the same reference over and over.

Try this:

$scope.addToCart = function(key, size, price) {


        //Add selected size and price

        //Add 'extra' for selected price and size
        var selectedProduct = {}; // new reference each time function is called
        selectedProduct.extra = {
            //price is a float
            price: price,
            //$scope.productSizes is a single array that
            //changes int values to sizes (1 => individual, 2 => medium ...)
            size: $scope.productSizes[size],
            //size is the int value of the size
            sizeInt: size
        };

        $scope.cart.push(selectedProduct);
};

Comments

0

In your addCart function you should redeclare selectedProduct this way: $scope.selectedProduct = {} . The reason - objects in javascript assigned by reference, and you have the same object in all array elements. So you are updating each one by reference when you changing extra.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.