dorcsi
dorcsi

Reputation: 325

Data gets updated when dialog is cancelled - Angular Material

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

I have a Material Dialog where a given list can be edited items can be added, deleted or modified). In my dialog there are two buttons: Cancel and Submit.

I wish to drop ALL THE CHANGES when I click on Cancel and I 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 class="material-dialog">
<h2 class="mat-dialog-title">My item list</h2>
    <p>Items:</p>
    <div id="mat-list-item-container" *ngFor="let item of data.itemListe"
        class="grid-container-two-delete grid-container">
        <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 class="grid-container-two">
        <div class="grid-item-left"><button class="button--secondary" type="button"
                (click)="onCancel()">Cancel</button>
        </div>
        <div class="grid-item-right"><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 that did not work.

What am I doing wrong?

Thanks a lot!

Upvotes: 1

Views: 1568

Answers (1)

rleffler
rleffler

Reputation: 470

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

Upvotes: 3

Related Questions