Jake Bown Jake Bown - 5 months ago 26
Javascript Question

Angular js push changing values in array

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

Answer

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);
};