Home > Back-end >  Data gets updated when dialog is cancelled - Angular Material
Data gets updated when dialog is cancelled - Angular Material

Time:04-05

I am facing the following issue and unfortunately I cannot see what wrong here.

I have a Material Dialog where a given list can be edited (new items can be added, another ones can be deleted or existing ones modified...). In my dialog there is two buttons, one Cancel and one Submit.

I wish to drop ALL THE CHANGES when I click on Cancel and do not want my list to be modified.

I have the following code:

constructor(public dialog: MatDialog) { }

@Input() myData: MyObjectType;

 openDialog() {
    const dialogRef = this.dialog.open(MyDialogComponent, {
        width: 'auto',
        data: { 'dataINeed': this.myData}
    });
    dialogRef.afterClosed().subscribe(rp => {
       console.log(rp);
}

And this is my MyDialogComponent:

constructor(
    public dialogRef: MatDialogRef<MyDialogComponent>,
    @Inject(MAT_DIALOG_DATA) public data: { 'dataINeed': MyObjectType},
) { }

deleteItem(item: ItemType) {
    this.data.itemListe.forEach(o => {
        if (o === item) {
            const index = this.data.itemListe.indexOf(o);
            this.data.itemListe.splice(index, 1);
        }
    });
}

valueChange(updatedValue: string, item: ItemType): void {
    this.data.itemListe[this.data.itemListe.indexOf(item)].propertyfield = updatedValue;
}

addItem() {
    const newItem: ItemType= {
        a: '',
        b: '',
        c: '',
        d: false,
        e: ''
    };
    this.data.itemListe.push(newItem);
}

onCancel() {
    this.dialogRef.close();
}

onSubmit() {
    this.dialogRef.close({ data: this.data })
}


<div >
<h2 >My item list</h2>
    <p>Items:</p>
    <div id="mat-list-item-container" *ngFor="let item of data.itemListe"
        >
        <mat-form-field appearance="outline" style="padding-right: 1em;">
            <input matInput (change)="valueChange($event.target.value, item)" [value]="item.c">
        </mat-form-field>
        <mat-icon svgIcon="delete_red" (click)="deleteItem(item)">
        </mat-icon>
    </div>
    <button mat-button (click)="addItem()">
        <mat-icon svgIcon="add_circle"></mat-icon>&nbsp;&nbsp;
        Add item
    </button>
</div>
<br>
<mat-dialog-actions>
    <div >
        <div ><button  type="button"
                (click)="onCancel()">Cancel</button>
        </div>
        <div ><button mat-button (click)="onSubmit()">OK</button></div>
    </div>
</mat-dialog-actions>

When I test it and delete some items, and rewrite the propertyfield of others and at the end click on Cancel, my dialog gets closed. If I open it again via the parent component, my changes are there. I cannot see why, hence I do not send any data back in my close method.

I tried to create a deep copy of my list and operate with that, but no success..

Any idea what do I make wrong?

Thanks a lot!

CodePudding user response:

You probably want to clone your data before passing it to your modal:

constructor(public dialog: MatDialog) { }

@Input() myData: MyObjectType;

 openDialog() {
    const dialogRef = this.dialog.open(MyDialogComponent, {
        width: 'auto',
        data: { 'dataINeed': cloneDeep(this.myData)}
    });
    dialogRef.afterClosed().subscribe(rp => {
       console.log(rp);
}

I typically use cloneDeep from the lodash library to make a deep clone. This will pass the cloned object to the dialog instead of a reference to your data. That way once it is closed the only way to get data back to the parent component/service is to get the result from the dialog

  • Related