-1

I have to deep clone an array of objects

  filterList: Filter[] = [
    new ChipsFilter('Rating', 'rating',
      [
        {
          name: '5 ★',
          key: '5',
          value: true
        },
        {
          name: '4 ★',
          key: '4',
          value: true
        },
        {
          name: '3 ★',
          key: '3',
          value: true
        },
        {
          name: '2 ★',
          key: '2',
          value: true
        },
        {
          name: '1 ★',
          key: '1',
          value: true
        }
      ]),
    new CheckboxFilter('Country', 'country', [
      {
        name: 'India',
        key: 'india',
        value: true
      },
      {
        name: 'Brazil',
        key: 'brazil',
        value: false
      },
      {
        name: 'UAE',
        key: 'uae',
        value: true
      },
      {
        name: 'Sri Lanka',
        key: 'sri-lanka',
        value: true
      },
      {
        name: 'USA',
        key: 'usa',
        value: false
      },
      {
        name: 'England',
        key: 'england',
        value: true
      },
      {
        name: 'South Africa',
        key: 'south-africa',
        value: true
      }
    ]),
    new CalendarFilter('Date', 'createdAt', [
      {
        name: 'Start Date',
        key: 'startDate',
        value: ''
      },
      {
        name: 'End Date',
        key: 'endDate',
        value: ''
      }
    ]),
  ];

After clone I want the data type of objects to be same but I get the object as the type instead, have tried below methods for cloning.

  1. Using JSON stringify
this.filterList = this.filterList.map(a => Object.assign({}, a));
  1. Using object.assign
this.filterList = this.filterList.map(a => Object.assign({}, a));
JJJ
  • 32,902
  • 20
  • 89
  • 102
Varun Sukheja
  • 6,170
  • 5
  • 51
  • 93
  • `Object.assign` used that way is not going to clone objects in a way that preserves type information. Depending on the structure of those classes (which you don't show) it may not clone them at all. – Jared Smith Jun 07 '19 at 18:06
  • Using Object.assign(...) says assign the second argument to the structure represented in the first argument - in this case, it is an Object object. – Randy Casburn Jun 07 '19 at 18:06
  • Possible duplicate of [typescript - cloning object](https://stackoverflow.com/questions/28150967/typescript-cloning-object) – Jared Smith Jun 07 '19 at 18:07

2 Answers2

0

The first argument to Object.assign() is the target object. That object effectively is the result. What Object.assign() does is just copy over own enumerable properties of your CalendarFilter instances to that target.

What you could do instead is create new instances of your objects in array.map() instead of assigning them to a generic object with Object.assign().

this.filterList = this.filterList.map(a => new CalendarFilter(...))

Of course, you need to use the right constructor for each type you encounter in your array.

Joseph
  • 117,725
  • 30
  • 181
  • 234
0

This will take into account the variable Object types:

class ChipsFilter {constructor(){this.chipsProp="chipsProp"}}
class CheckboxFilter {constructor(){this.checkboxProp= "checkboxProp"}}
class CalendarFilter {constructor(){this.calendarProp= "calendarProp"}}

const filterList = [
  new ChipsFilter(),
  new CheckboxFilter(),
  new CalendarFilter(),
];

let out = filterList.map(obj=>Object.assign(new obj.constructor, obj));
console.log(out[0].constructor, out[0]);
console.log(out[1].constructor, out[1]);
console.log(out[2].constructor, out[2]);
Randy Casburn
  • 13,840
  • 1
  • 16
  • 31