Search code examples
angulartypescriptjhipstercolor-picker

Angular 4 : copy an array to save initial values but both arrays are updated by the form


I'm a beginner and working on an app built with JHipster and using Angular 4.3.

I'm working on a form in which a user can edit colors. I have to save the initial values in case a user edits colors, but doesn't finally validate the save (confirmation modal). So I have to return to the initial values. But actually, when I make a copy of the initial values, both arrays are updated by the form values.

My code looks like this :

export class MyComp implements OnInit {
    initialColors: Color[]; // the object Color has an id, a name and a rgb as attributes
    colors: [];

    constructor(private service: ColorService, private confirmationDialogService: ConfirmationDialogService) {}

    ngOnInit() {
        this.getColors();
    }

    getColors() {
        this.service.query.subscribe(
            this.colors= res.json;
            this.initialColors= Object.assign([], this.colors); // I've tried with res.json too
        },
            (res: ResponseWrapper) => this.onError(res.json)
        );
    }

    submitColors(form) {
        this.confirmationDialogService.confirm('Validation','Do you want to save changes ?')
        .then((confirmed) => {
            if (confirmed === true) {
                // stuff to save is OK
            } else { // want to return to initial state
                this.colors= this.initialColors;
    }
}

But the problem is that initialColors has taken the same values than colors... (when I do console.log both arrays have the same rgb updated by the form)

My form looks like this :

<form #colorForm="ngForm" (ngSubmit)="submitColors(colorForm.form.value);">
            <table>
                <tr *ngFor="let c of colors| orderBy: 'id';">
                    <td>{{c.label| translate}} :</td>
                    <td>
                        <input type="color"
                               [(ngModel)]="c.color"
                               #nameField="ngModel"
                               name="{{c.label}}"
                               (ngValue)="c.color"
                               [ngStyle]="{'color-rendering': c.color}"/>
                    </td>
                </tr>
            </table>
            <button type="submit" class="btn btn-sm">
                <span class="fa fa-save"></span>
                <span class="d-none d-md-inline" jhiTranslate="entity.action.save">Save</span>
            </button>
        </form>

Does anyone have an idea ?


Solution

  • Dont' use Object.assign([], anotherArr) and don't assign colors to initialColors. Clone it. You can use lodash library to clone array like this:

    submitColors(form) {
            this.confirmationDialogService.confirm('Validation','Do you want to save changes ?')
            .then((confirmed) => {
                if (confirmed === true) {
                    // stuff to save is OK
                } else { // want to return to initial state
                    // 
    
                    this.colors= _.cloneDeep(this.initialColors);
        }
    

    Code example

    In your case in two array object references are the same:

    this.colors[0] == this.initialColors[0] // true
    

    Therefore, your editing the same array of objects in form

    If you can't you lodash for some reason. Deep copying array of nested objects in javascript