Angular form retains the previous value when saving

I encountered an issue with my form component where it displays previous values instead of updated ones during a save operation. The strange part is that if I close the form and reopen it, the new values are then shown correctly. It seems like the problem lies in the fact that the old values stored in 'selectedContact' are being passed into the form as 'contactForm' during the save process, causing the new values to be overwritten by the old ones on the form controls. My data management is handled using NgRx Store.

I'm unsure how to prevent the form from displaying old values when saving. Is there a way to pause the form from updating?

Parent modal component:

@Component({
  selector: 'parent-modal',
  template: `
    <ng-template #childTemplate>
      <contact-form
        [contactForm]="contactForm"
        [loading]="(loading$ | async)!"
        (cancel)="close()"
        (save)="save($event)"
        *ngIf="contactForm"
      ></contact-form>

    <web-modal
      [childTemplate]="childTemplate"
      [visible]="(isPopupOpen$ | async)!"
      (cancel)="close()"
    >
    </web-modal>
  `,
  styles: [],
})
export class ContactModalComponent {
  @Input() public selectedContact!: Contact | null;
  public isPopupOpen$!: Observable<boolean>;
  public loading$: Observable<boolean>;

  public constructor(
    private store: Store<ContactPartialState>,
    configurationStore: Store<ConfigurationState>,
  ) {
    this.isPopupOpen$ = store.select(contacttQuery.getIsContactOpen);
    this.loading$ = store.select(contactQuery.getLoading);
  }

  public get contactForm(): Contact {
    return this.selectedContact as Contact;
  }

  public close(): void {
    this.store.dispatch(closeContact());
  }

  public save(form: Contact): void {
    this.store.dispatch(saveContact({ payload: form }));
  }
}

Child form component:

@Component({
  selector: 'contact-form',
  templateUrl: '../contact-form/contact-form.component.html',
})
export class ContactFormComponent implements OnChanges {
  @Input() public contactForm!: Contact | null;
  @Input() public loading: boolean;
  @Output() public cancel: EventEmitter<void>;
  @Output() public save: EventEmitter<Contact>;

  public form!: FormGroup;

  public constructor(
    fb: FormBuilder,
  ) {
    this.loading = false;
    this.cancel = new EventEmitter<void>();
    this.save = new EventEmitter<Contact>();
    this.contactForm = new Contact();
    this.createForm();
  }

  public ngOnChanges(): void {
    this.createForm();
  }

  public createForm(): void {
    // add form controls
  }

  public emitCancel(): void {
    this.cancel.emit();
  }

  public emitSave(): void {
    this.form.markAllAsTouched();
    if (this.form.valid) {
      const contact = new Contact(this.form.value);
      this.save.emit(contact);
    }
  }
}

Answer №1

Make sure to always update the selectedItem variable within your ProductModalComponent.

export class ProductModalComponent {
  public submit(form: Product): void {
    this.selectedItem = form;
    this.service.sendDataToServer({ payload: form });
  }
}

Answer №2

Here are a few solutions to work around this issue.

  1. To solve the problem, adjust your form creation to only occur once in the ngOnChange method:

    public ngOnChanges(changes:SimpleChanges): void {
        if(changes.contactForm.isFirstChange()){
            this.createForm();
      }  
    }
    
  2. If there is a specific UUID present in your form, you can set it up to trigger an update in the form within the ngOnChangeHook:

    ngOnInit(){
        this.activeId$.pipe(
            takeWhile(()=>this.componentAlive),
            distinctUntilChanged()
        ).subscribe(){
          this.createForm()
        }
    }
    public ngOnChanges(changes:SimpleChanges): void {
        if(changes.contactForm.id){
            activeId$.next(this.contactForm.id)
        }  
    }
    
    ngOnDestroy(){
       this.componentAlive = false;
    }
    
    activeId$ = new BehaviorSubject(null);
    componentAlive = true;
    
  3. Alternatively, you can simply create the form using a different lifecycle hook:

    ngOnInit(){
      this.createForm()
    }
    

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

The beta version of Angular 2.0 introduces the BrowserDomAdapter for easy access to the DOM

I have a Component in Angular 2.0 that is attempting to utilize the DOM Adapter API from Angular's BrowserDomAdapter documentation. The initialization of this DomAdapter can be found here. However, I am uncertain about whether the Dom Adapter needs t ...

The FlatList glides effortlessly in any direction

My FlatList allows me to drag and move it in all directions (up/down/right/left) even though it appears vertically due to styling. The scroll bar still shows horizontally, which I want to disable. How can I achieve this? This is the code snippet for using ...

Tips on how to confirm that the content of the angular form begins and concludes with a specific string

For user input that must start with a specific string, such as XYZ, have business data in between, and end with ENDXYZ within a textview, I am utilizing the Angular framework for the UI. <div class="mb-3 col-md-5"> <label for=&qu ...

Angular2 encountered a TypeError stating that self._el_11 is not a valid function

Looking to attach an event listener to an input field? Check out the code snippet below: <input ref-search (keyup)="search(search.value)"> Here is the corresponding search method: search(condition: string){ console.log(condition); } When ente ...

Using Typescript for the factory design pattern

My goal is to develop a factory for generating instances of MainType. To achieve this, I want to reuse existing types (specifically the same instance) which are stored in the ItemFactory. class BaseType { } class MainType extends BaseType { } class It ...

Turn off ESLint for TypeScript documents

I am faced with a large web application that consists of legacy JavaScript code (with eslint) and new TypeScript code (with tslint). The issue I am encountering is that my IDE (WebStorm) is running both linters on all files, causing me to receive eslint e ...

Is there a way to insert data from one table into a MySQL Table in Drizzle and update the entry if it already exists?

My goal is to utilize Drizzle for inserting data into a table and updating it if the key already exists. In MySQL, the code would look like this: INSERT INTO myTable1(field1,field2,field3,field4) SELECT fieldOne,fieldTwo,fieldThree,fieldFour FROM myTable2 ...

What does it signify when it is stated that "it is not a descendant of the indexer"?

Currently, I am diving into Typescript with the help of this informative guide on indexer types. There is a specific piece of code that has me puzzled: interface NumberDictionary { [index: string]: number; length: number; // okay, length shoul ...

Find out if all attributes of the object are identical

I am trying to create the boolean variable hasMultipleCoverageLines in order to determine whether there are multiple unique values for coverageLineName within the coverageLines items. Is there a more efficient way to write this logic without explicitly c ...

I encountered an error in my Node.js application stating that it could not find the name 'Userdetailshistory' array. I am puzzled as to why this error is occurring and I suspect it may be due to my

import { Component, OnInit } from '@angular/core'; import { UserdetailshistoryService } from '../../services'; @Component({ selector: 'my-userdetailshistory', templateUrl: './userdetails-history.component.html', ...

The child module is unable to locate the route URL for the parent module

I'm new to Angular and I'm working on organizing my code into modules. So far, I have an admin module that responds to the /admin request, but now I want to add a child module called Portfolio Module. Everything is working fine, except for the f ...

TypeScript encounters a self-referencing type alias circularly

Encountering an issue with Typescript 3.6.3, specifically getting the error: Type alias 'JSONValue' circularly references itself. View code online here In need of assistance to resolve the circular reference in this specific version of TS (note ...

Tips for avoiding storage issues in Angular Server-Side Rendered application using guards and services (Angular V17)

Is there a way to prevent undefined localStorage/Sessionstorage errors in Angular V17 SSR apps without using the old platformId? I am looking for an equivalent of afterNextRender that can be used in services or guards, whether they are functional guards or ...

Tips for creating a default route with parameters in Angular Component Router?

I am trying to set a default route in my sub-component (using useAsDefault: true) and have parameters automatically passed to it, but I can't seem to find any information on how to accomplish this in the documentation. I have a parent component with t ...

Ensure that the specified Class type must have a constructor with no arguments

When working with a function that takes a parameter representing a Class (not an object or instance, but the Class itself), or essentially a variable assigned to a Class. The challenge is ensuring that the Class assigned to the parameter has a constructor ...

Develop an rxjs pipeline that merges values according to their type prior to executing them in an async manner using concatMap

In my code, there's an eventStream that deals with different types of events and sends them to the server via HTTP. import { from, Observable } from 'rxjs'; import { concatMap } from 'rxjs/operators'; type Update = number[]; inte ...

What is the best way to store the output of a function in a local variable?

In my Type Script code, I am looking to store the return value of a function in a local variable. The process is outlined below: getdetail1(store){ let Cust_id=this.sharedata.latus_lead.m_type let url="http:domain.com" console.lo ...

Guide on implementing Password Confirmation in Angular 7 User Registration

I am currently working on a project that involves creating a user registration form using Angular 7 for the frontend and Laravel 5.8 for the backend. While I have successfully implemented user password confirmation in the backend, I am facing some challeng ...

Simulating service calls in Jest Tests for StencilJs

When testing my StencilJs application with Jest, I encountered an issue with mocking a service class method used in a component. The service class has only one function that prints text: The Component class: import {sayHello} from './helloworld-servi ...

Refreshing Angular2 View After Form Submission

Currently, I am in the process of developing a basic CRUD application with Angular2. The application comprises of a table that displays existing records and a form for adding new records. I am seeking guidance on how to update the table to show the new rec ...