Cannot get an object's properties in a form

74 Views Asked by At

I have a form, which looks like this

 <form [formGroup]="editPersonForm" class="dialog__form">
            <mat-form-field appearance="outline" class="dialog__field">
                <mat-label>Фамилия</mat-label>
                <input matInput placeholder="Фамилия" formControlName="surname">
            </mat-form-field>
            <mat-form-field appearance="outline" class="dialog__field">
                <mat-label>Имя</mat-label>
                <input matInput placeholder="Имя" formControlName="name">
            </mat-form-field>
            <mat-form-field appearance="outline" class="dialog__field">
                <mat-label>Отчество</mat-label>
                <input matInput placeholder="Отчество" formControlName="father_name">
            </mat-form-field>
            <mat-form-field appearance="outline" class="dialog__field">
                <mat-label>Дата рождения</mat-label>
                <input [matDatepicker]="birthdate" matInput
                    formControlName="birthdate" name="birthdate">
                <mat-datepicker-toggle matSuffix [for]="birthdate"></mat-datepicker-toggle>
                <mat-datepicker #birthdate ng-model-options="{ timezone: 'utc' }"></mat-datepicker>
            </mat-form-field>
            <mat-form-field appearance="outline" class="dialog__field">
                <mat-label>Номер телефона</mat-label>
                <input matInput placeholder="Номер телефона" formControlName="phone_num">
            </mat-form-field>
        </form>

In the .ts file in the ngOnInit hook I first get a person by its id and then want to put its fields values into the form controls, the problem is that while ngOnInit is still working the person remains undefined and the form controls remain empty, how can I solve this issue? Here is the .ts code:

ngOnInit(){
  this.personService.getPersonById(this.guard.person_id).subscribe((person) => {
    this.person = person
    
  });
  this.editPersonForm = this.fb.group({
    surname: [this.person.surname,Validators.required],
    name: [this.person.name,Validators.required],
    father_name: this.person.father_name,
    birthdate: this.person.birthdate,
    phone_num: this.person.phone_number,
  })

the form errors in the console

I expect all the person's values to be in the inputs

2

There are 2 best solutions below

1
On BEST ANSWER

The issue with your code is that the form controls are being initialized before the person object is defined. You can modify ngOnInit hook like this

ngOnInit(){
  this.editPersonForm = this.fb.group({
     surname: ['',Validators.required],
     name: ['',Validators.required],
     father_name: '',
     birthdate: '',
     phone_num: '',
  })
  this.personService.getPersonById(this.guard.person_id).subscribe((person) => {
    this.person = person;
    const { birthdate, name, father_name, phone_num, surname } = person;
    this.editPersonForm.patchValue(person);
    this.editPersonForm.updateValueAndValidity();
  });
}

In above code, the form controls are initialized with empty values in the ngOnInit hook, and then the person data is retrieved inside the subscribe method. The patchValue method is then used to update the form controls with the person data. This way, the form controls will be correctly populated with the person data.

2
On

It is because due to the asynchronous nature of the getPersonById method.When you subscribe to it, the callback function inside the subscribe block is executed when the data is available, which means that the form controls are being initialized with the person's data before the data is fetched.

ngOnInit(){
  this.personService.getPersonById(this.guard.person_id).subscribe((person) => {
    this.person = person
    this.editPersonForm = this.fb.group({
       surname: [this.person.surname,Validators.required],
       name: [this.person.name,Validators.required],
       father_name: this.person.father_name,
       birthdate: this.person.birthdate,
       phone_num: this.person.phone_number,
    })
    
  });