Tips for preventing bidirectional data binding in Angular 8

I am currently working on an Angular 8 app and I've encountered an issue with data-binding.

The problem arises when trying to edit a specific entry in a table containing data. In the app.component.html file, I have the following code:

<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 file, there is a corresponding function:

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

When the user clicks on the edit icon, a modal opens up allowing them to edit the selected entry. The modal implementation is within the same app.component.html file.

<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>

Thanks to two-way data-binding, any edits made in the form inside the modal reflect directly on the table entry being edited. Upon clicking the "Save" button, the editEntrySaveBtnPressed() function gets triggered, updating both the database and the template table.

If the user decides to cancel the editing process by clicking the "Cancel" button, the closeModal() function closes the modal. However, it seems that the changes are still reflected in the table even after cancellation.

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 suggestions on why the table in the template doesn't revert back to its original state upon cancellation?

Appreciate your assistance!

Answer №1

Ensuring the reference is properly shared between the objects entry and edittedEntry can be done with the following code snippet:

this.edittedEntry = entry; 

To correctly copy the values of entry to edittedEntry, it is recommended to use Object.assign({}, entry} or {...entry}.

When updating and saving, utilize the index to update the values back into the entry like so:

this.entry[selectedIndex] = {...this.edittedEntry}

Answer №2

The reason for this behavior is that you are assigning a reference to the edittedEntry. This is how reference types operate. To solve this issue, simply create a new object based on the existing object entry.

edittedEntry: any;

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

In Typescript, encountering a member of a union type with an incompatible signature while utilizing the find method on an array of

I need to verify if a specific value exists within an array of objects. The structure of my array is as follows: [ 0: { id: 'unique_obj_id', item: { id: 'unique_item_id', ... }, ... }, 1: {...} ] The objects in the ar ...

The package and package-lock files are out of sync when executing npm ci

Currently facing an issue while attempting to deploy my application on Heroku. The problem arose when trying to run the frontend, specifically with: `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are ...

Using TypeScript: Incorporating a map function in type declarations

My current situation involves the following types: type Value = boolean | number | string class Struct<T extends Value[] = Value[]> { constructor(fmt: string) { } pack(...args: T): Buffer { } } I am seeking guidance on how to replace &l ...

Interacting between two occurrences of the identical Angular component

Within a Razor view, I include an angular component: <my-widget id="myWidget" isfullscreen="false" class="some-class"></my-widget> Upon clicking the 'Popup' button, a popup appears in an iframe and the s ...

How to resolve: "Error: Cannot access 'Id' property of undefined" in Node.js using TypeScript

My code is giving me trouble. I am attempting to locate an element in an array using the following code snippet Name() { console.log(LoadItems.ItemConfigs); var ItemConfig = LoadItems.ItemConfigs.find(itemconf => itemconf.Id === this.ConfigId); ...

Implement a system in Angular Service that automatically generates user IDs for an array of user inputs

How can I automatically increment the user ID for each new user input and use that value for deletion or updating of specific entries? If a user adds their details as shown in the output picture link below, I want to display the output in a similar format ...

Error: The property '...' is not found in the ReactElement<any, any> type, but it is required in the type '{...}'

As a beginner in TypeScript, I am currently working on rendering a page by fetching data from getStaticProps. The code snippet I am using for this purpose is: import React, {FormEvent, useState} from "react"; import { InferGetStaticPropsType } fr ...

Ways to turn off the keyboard shortcuts in Storybook

Currently, I am utilizing version 6.0.25 of Storybook for the documentation of one of my Vue projects. Within this project, I am navigating between records using the less than and greater than buttons on the keyboard. However, an issue arises when I pres ...

Make sure to search for the "Not in" condition in an Angular 2 template list

I'm currently working with a template that looks like this: <span *ngIf="item.status !=='E1' && item.status !=='B' && item.status !=='R'">{{item.status_desc}}</span> Although the ngIf condit ...

Launch another modal and then deactivate the initial modal

Having two Modals has presented a challenge for me when it comes to closing the first modal after the second one is opened. I attempted a solution, but it prevented the second Modal from opening altogether. This code snippet below belongs to the first Mo ...

Add a decorator to all functions in a TypeScript class to list all available methods

How can I apply a decorator function to all methods within a class in order to streamline the code like this: class User { @log delete() {} @log create() {} @log update() {} } and have it transformed into: @log class User { ...

Angular and Bootstrap join forces to create collapsible rows

I'm implementing bootstrap collapse feature to display a details row upon clicking a button. However, the details row always appears below the first row instead of below the selected row. How can I make it show up below the clicked row? Here is my cod ...

Could routerLinkActive be used to substitute a class rather than simply appending one?

I have a navigation bar icon that links to an admin route. I want this icon to change its appearance when on that specific route. To achieve this, I can simply replace the mdi-settings-outline class with mdi-settings, displaying a filled version of the sam ...

Trigger a post request by clicking the button to generate an excel report for download

I am attempting to download an excel file by making a POST call upon clicking a button in AngularJS. The Java controller I am working with returns void. This is the service code used to write to the excel file: response.setContentType("application/ms-exc ...

Troubleshooting a problem with loading micro front-end assets within the main application

With the use of Angular and React Js, I have successfully developed two micro apps along with a base/container app in Angular. The micro apps are each running on different ports, with the base app importing the main.js file from these specified ports. Th ...

Is it feasible for a React-based shell to host or load an Angular component using Module Federation in Webpack 5?

I am currently developing a web application using Angular that will be embedded or loaded from another web application built with React. I am unsure if this integration can be achieved using webpack 5's module federation. Module federation involves l ...

How to Use Angular 2 to Eliminate Unnecessary Commas in a Text/CSV

Seeking assistance with removing extraneous commas from a file, using the code snippet below: const data: any = utils.sheet_to_csv(ws); let blob = new Blob(['\ufeff' + data], { type: 'text;charset=utf-8;' }); let dwldLink = docum ...

Discover the callback function parameter's type in TypeScript

When passing a callback function as a parameter, I find it important to determine the type of this parameter without having to manually define it myself. Is there an easier way to obtain a type alias for this situation, rather than relying on VSCode's ...

Arrangement of code: Utilizing a Node server and React project with a common set of

Query I am managing: a simple react client, and a node server that functions as both the client pages provider and an API for the client. These projects are tightly integrated, separate TypeScript ventures encompassed by a unified git repository. The se ...

Dockerized Nginx: Struggling with location configuration issues

Here is the docker file: FROM nginx:1.17.4-alpine # copy artifact build from the 'build environment' COPY ./dist /usr/share/nginx/html/ COPY ./default.conf /etc/nginx/conf.d/ # expose port 80 EXPOSE 80 # run nginx CMD ["nginx", "-g", "daemon o ...