Search code examples
javascriptarraysobjectpass-by-referencepass-by-value

Assigning array inside object in Javascript


I have cart and products global variable.

Products can have multiple attributes.

Here is a code

var products = [
                  {
                    name: 'Table',
                    price: 200,
                    attributes: [
                                  {
                                    name: 'Height',
                                    type: 'text',
                                    default_value: '',
                                  },
                                  {
                                    name: 'Width',
                                    type: 'text',
                                    default_value: '',
                                  }
                                ],
                  },
                  {
                    name: 'Chair',
                    price: 150,
                    attributes: [
                                  {
                                    name: 'Height',
                                    type: 'text',
                                    default_value: '',
                                  },
                                  {
                                    name: 'Width',
                                    type: 'text',
                                    default_value: '',
                                  },
                                  {
                                    name: 'Company',
                                    type: 'text',
                                    default_value: ''
                                  }
                                ],
                  }
              ];

var cart = {
  products: [],
};

//console.log('Initial cart',cart);

//add product to cart
let p = Object.assign({},products[0]);
cart.products.push(p);

//console.log('First cart', cart);
//change price
cart.products[0].price = 20;
//console.log('products',products);
//console.log('second cart',cart);

//change attribute of product
cart.products[0].attributes[0].value = 5;

This code changes global products value attributes instead of cart attributes.

Please help me to solve this issue.


Solution

  • From MDN

    Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.

    And as products[0] is an object in your data that's why you are facing this shallow copy issue

    Instead you can use

    let p = JSON.parse(JSON.stringify(products[0]));
    

    var products = [{
            name: 'Table',
            price: 200,
            attributes: [{
                    name: 'Height',
                    type: 'text',
                    default_value: '',
                },
                {
                    name: 'Width',
                    type: 'text',
                    default_value: '',
                }
            ],
        },
        {
            name: 'Chair',
            price: 150,
            attributes: [{
                    name: 'Height',
                    type: 'text',
                    default_value: '',
                },
                {
                    name: 'Width',
                    type: 'text',
                    default_value: '',
                },
                {
                    name: 'Company',
                    type: 'text',
                    default_value: ''
                }
            ],
        }
    ];
    
    var cart = {
        products: [],
    };
    
    //console.log('Initial cart',cart);
    
    //add product to cart
    let p = JSON.parse(JSON.stringify(products[0]));
     
    cart.products.push(p);
    
    //console.log('First cart', cart);
    //change price
    cart.products[0].price = 20;
    console.log('products',products);
    console.log('second cart',cart);