0

I'm building an app in Angular 8 and I have the following problem regarding data-binding.

I have a table with data. I want to edit a specific entry. So, in the app.component.html, I have:

<table>
   <tr *ngFor="let entry of entries">
      <th>{{ entry.asset }}</th>
      <th>{{ entry.model }}</th>
      <th>{{ entry.ip }}</th>
      <th>
         <a (click)="editIconPressed(entry)"><i class="material-icons">create</i></a>
      </th>
   </tr>
</table>

In the app.component.ts, I have the corresponding function:

editIconPressed(entry: Entry): void {
   this.edittedEntry = entry;
   this.showEditModal = true;   
}

With the variable showEditModal, a modal is opened in order the selected entry to be editted. The code for the modal is inside the same file, app.component.html.

<div class="modal" [style.display]="showEditModal ? 'block' : 'none'">
   <div class="modal-content edit-entry-modal-width">
      <form #editEntryForm="ngForm">
         <input class="edit-entry-form-input-field" type="text" [(ngModel)]="edittedEntry.asset" name="model">
         <input class="edit-entry-form-input-field" type="text" [(ngModel)]="edittedEntry.model" name="serial">
         <input class="edit-entry-form-input-field" type="text" [(ngModel)]="edittedEntry.ip" name="serial">
         <button class="btn btn-success" type="submit" (click)="editEntrySaveBtnPressed()">Save</button>      
      </form>
      <button class="btn btn-primary" (click)="closeModal()">Cancel</button>
   </div>
</div>

So, the user can edit the form and automatically, because of the two-way data-binding, the table entry behind the modal will change as well. If the user pushes the "Save" button, editEntrySaveBtnPressed() function is called and the database is updated, as well as the table inside the template.

However, if the user pushes the "Cancel" button, the closeModal() function is called which is just closing the modal. Unfortunatelly, the change on the table in the template is remaining although the user cancelled the edit.

editEntrySaveBtnPressed(): void {  
            this.entryService
                .editEntry(this.edittedEntry)
                .subscribe(res => {
                    this.edittedEntry = { _id: '', asset: '', model: '', ip: '' };
                    this.showSuccessMsgForEdit = true;
                    setTimeout(() => { this.closeModal(); } , 2000);
                }, err => {
                    this.errorMsg = err;
                    this.showErrorMsg = true;
                });
}

closeModal(): void {
        this.edittedEntry = { _id: '', asset: '', model: '', ip: '' };
        this.showEditModal = false;
}

Any ideas for the change not being passed on the table inside the template??

Thank you for your help!!!

2
  • Well, create a copy of the entry before edting it. When saving, replace the original entry by the edited copy. Commented Dec 10, 2019 at 18:10
  • 1
    use spread operator to get a copy this.edittedEntry = {...entry}; and a variable 'indexto store the index selected, then in ok, use entries[index]={...this.edittedEntry}. Othe aproach is make a copy of old values this.oldValues={...entry}, and in cancel use entries[index]={...this.oldValues}` Commented Dec 10, 2019 at 18:10

2 Answers 2

3

You are sharing the reference between the objects entry and edittedEntry in the below line

 this.edittedEntry = entry; 

hence need to use Object.assign({}, entry} or {...entry} when copying the values of entry to edittedEntry.

When saving use the index to update the values back in to the entry something like,

this.entry[selectedIndex] = {...this.edittedEntry}
Sign up to request clarification or add additional context in comments.

1 Comment

It works, but I suppose you mean entries insteed of entry. I editted it. Thanks for your help.
2

It happens because you are assigning reference to the edittedEntry. This is how reference types works. So just create a brand new object from existing object entry.

edittedEntry: any;

editIconPressed(entry: Entry): void {
   this.edittedEntry = JSON.parse(JSON.stringify(entry));
   this.showEditModal = true;   
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.