Angular 2: Array declared with const is modified

0

I have the following problem, I have been trying to find the answer for a few hours, I put it in context.

I have this code. in a theme.model.ts

 interface spectrum{
   shade: string;
   hex: string;
   contrast: string;
 };


 interface palette {
   colorName: string;
   values: spectrum[];

 };

 interface mono {
   colorName: string;
   hex: string;
 };

 const monos: mono[] = [{
                    colorName: 'Black',
                    hex: '#000000'
                },{
                    colorName: 'White',
                    hex: '#FFFFFF'
                }]; 


 const palettes: palette[] = 
    [

    {
    colorName: 'Red',
    values: [
        { shade: '50' ,   hex: '#FFEBEE'  , contrast: '#000000' },
        { shade: '100' ,  hex: '#FFCDD2'  , contrast: '#000000' },
        { shade: '200' ,  hex: '#EF9A9A'  , contrast: '#000000' },
        { shade: '300' ,  hex: '#E57373'  , contrast: '#000000' },
        { shade: '400' ,  hex: '#EF5350'  , contrast: '#000000' },
        { shade: '500' ,  hex: '#F44336'  , contrast: '#000000' },
        { shade: '600' ,  hex: '#E53935'  , contrast: '#000000' },
        { shade: '700' ,  hex: '#D32F2F'  , contrast: '#000000' },
        { shade: '800' ,  hex: '#C62828'  , contrast: '#000000' },
        { shade: '900' ,  hex: '#B71C1C'  , contrast: '#000000' },
        { shade: 'A100' , hex: '#FF8A80'  , contrast: '#000000' },
        { shade: 'A200' , hex: '#FF5252'  , contrast: '#000000' },
        { shade: 'A400' , hex: '#FF1744'  , contrast: '#000000' },
        { shade: 'A700' , hex: '#D50000'  , contrast: '#000000' }]
    },
    {
    colorName: 'Pink',
    values: [
        { shade: '50' ,   hex: '#FCE4EC'  , contrast: '#000000'  },
        { shade: '100' ,  hex: '#F8BBD0'  , contrast: '#000000'  },
        { shade: '200' ,  hex: '#F48FB1'  , contrast: '#000000'  },
        { shade: '300' ,  hex: '#F06292'  , contrast: '#000000'  },
        { shade: '400' ,  hex: '#EC407A'  , contrast: '#000000'  },
        { shade: '500' ,  hex: '#E91E63'  , contrast: '#000000'  },
        { shade: '600' ,  hex: '#D81B60'  , contrast: '#000000'  },
        { shade: '700' ,  hex: '#C2185B'  , contrast: '#000000'  },
        { shade: '800' ,  hex: '#AD1457'  , contrast: '#000000'  },
        { shade: '900' ,  hex: '#880E4F'  , contrast: '#000000'  },
        { shade: 'A100' , hex: '#FF80AB'  , contrast: '#000000'  },
        { shade: 'A200' , hex: '#FF4081'  , contrast: '#000000'  },
        { shade: 'A400' , hex: '#F50057'  , contrast: '#000000'  },
        { shade: 'A700' , hex: '#C51162'  , contrast: '#000000'  }]
    }
    ];
  export { palettes,spectrum, monos, palette };

My question is if I make a simple assignment in a component (Assume the import of the model is correct) like this:

 private miArray: palette[] = [];

 miArray = palettes;

If I modify myArray, why will also palettes be modified? I have come to think one thing and that is that since the arrays are not of primitive type this has references to the original array in this case palettes and if I modify my clear array, palettes will be modified.

In case this is true, What would be the best way to work with this array like this?

It's the only question I have. Thanks.

    
asked by vdsancheza 20.01.2018 в 03:01
source

2 answers

1

Make a copy of the Array, using the slice() method

var array = [1, 2, 3]

var miArray = array.slice()

miArray[0] = 10

console.log('Array Original', array)

console.log('Array Modificado', miArray)

NOTE This only works if primitive elements are modified in the Array, (not the objects that may be in the Array)

In the following, I propose a cloning of Objects and Arrays, using recursive functions, thus allowing any level of depth within the Array / Object.

Tested in jsPerf , we can see that it is much more efficient, than passing it to string and converting it back to an object.

var array = [{a: '1', b: '2', c: [{a : 1, b: 2}]}]

var miArray = cloneArray(array)

miArray[0].a = 10
miArray[0].c[0].a = 10

console.log('Array Original', array)

console.log('Array Modificado', miArray)


function cloneObject(obj) {
  let clone = {}
  for(let prop in obj) {
    let value = obj[prop]
    if(Array.isArray(value)) {
      clone[prop] = cloneArray(value)
    } else if(typeof value == 'object') {
      clone[prop] = cloneObject(value)
    } else {
      clone[prop] = value
    }
  }
  return clone
}

function cloneArray(arr) {
  return arr.map(el => {
    if(Array.isArray(el)) {
      return cloneArray(el)
    } else if(typeof el == 'object') {
      return cloneObject(el)
    }
    return value
  })
}
    
answered by 20.01.2018 / 11:08
source
0

I found something that supports my hypothesis: Link

And the best alternative that occurred to me was Converting that array to string and vice versa, as follows:

var arr = [{a:1}, {a:2}, {a:3}]

var arrString = JSON.stringify(arr);

var arrStringToArray = JSON.parse(JSON.stringify(arr))

console.log('arr (Array):');
console.log(arr);
console.log('arr transformado en string:');
console.log(arrString);
console.log('arr transformado de String a Array:');
console.log(arrStringToArray);
    
answered by 20.01.2018 в 04:24