angulartypescriptformslifecyclengoninit

Cannot get an object's properties in a form


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


Solution

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