Search code examples
javascriptangulartypescriptclonedeep-copy

Deep copy, children still refer to original object


I have a problem with deep copy/clone on a object (TypeScript,Angular4,Ionic3) that also holds a list of other objects. Whenever I change the child objects in the copy, the original is also inflicted by the change and vice versa. My REST API gives me the following JSON back:

enter image description here

I have 2 types of objects that are relevant in this case, there are more but they do not need to be changed, therefore I do not include those:

import { Declaration } from './declaration.entity';

export class Period{
    constructor(
        public number: number,
        public status: string,
        public year: number,
        public month: number,
        public sum: number,
        public orderNumber: string,
        public userId: string,
        public submitDate: Date,
        public comment: string,
        public declarations: Declaration[]
    ){}
}

And

import { FileCustom } from './file.entity';
import { Period } from './period.entity';

export class Declaration{
    constructor(
        public id: number,
        public status: string,
        public name: string,
        public description: string,
        public amount: number,
        public date: Date,
        public period: Period,
        public userId: string,
        public files: FileCustom[],
        public comment: string   
    ){}
}

I want to change the field of a Declaration that is inside a Period. I have a object called periods (list of periods), which I want to clone. I need periods to be untouched. I looked at some other topics with possible solutions and tried them:

let cloned = this.periods.map(x => Object.assign({},x));

And

let cloned = this.periods.map(x => Object.assign([],x));

From this topic:

Deep copy an array in Angular 2 + TypeScript

When I use one of the above solutions and change for example the comment field of the period in the copy, the original file remains untouched. But when I change the comment field of the declaration inside the period, the original file is also changed, which is what I want to prevent. How can I deep copy/clone my list of periods without any children having any references to the original?

Thanks in advance.


Solution

  • If the object prototypes aren't an issue and objects don't contain functions you could JSON.stringify() and parse that back to new object

    let cloned = this.periods.map(x => JSON.parse(JSON.stringify(x)));
    

    Or stringify whole this.periods at one time

    let cloned = JSON.parse(JSON.stringify(this.periods))