Home > Software engineering >  How to write back nested properties with Angular reactive forms?
How to write back nested properties with Angular reactive forms?

Time:04-20

How to populate properties with Angular reactive forms?

Today I started to use reactive forms a little more intensively and immediately encountered a problem of understanding. Before I always wrote my forms with ngModel and built something like this:

<input [(ngModel)]="data.name" />
<input [(ngModel)]="data.setings.property1" />
<input [(ngModel)]="data.setings.property2" />

With reactive forms it would look like this:

<form [formGroup]="myForm">
    <input formControlName="name" />
    <input formControlName="property1" />
    <input formControlName="property2" />
</form>

** Compoennt Init **

this.myForm = this.fb.group({
    name: new FormControl({ value: this.data.name }, [Validators.required, Validators.minLength(3)]),
    property1: new FormControl({ value: this.data.setings.property1 }, Validators.required),
    property2: new FormControl({ value: this.data.setings.property2 }, Validators.required),
})

So far so good. My problem now is: how do I get the changed values back to this.data? The only thing I found is something like:

this.myForm.valueChanges.subscribe(val => {
    ....
});

Since my real data structure is relatively complex and contains many nested properties, I would now have to assign everything manually, a'la:

if (val == 'property1')
    data.setings.property1 = val;
else if 
    ...

That seems very complicated to me. Since something like this can be done quickly and easily with ngModel, I'm wondering whether there isn't a similarly comfortable option for reactive forms?

CodePudding user response:

You can use nested FormGroups

See this example using FormGroupName

This way, when instantiating the form:

form = new FormGroup({
    name: new FormGroup({
      first: new FormControl('Nancy', Validators.minLength(2)),
      last: new FormControl('Drew', Validators.required)
    }),
    email: new FormControl()
});

in the HTML:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
      <p *ngIf="name.invalid">Name is invalid.</p>

      <div formGroupName="name">
        <input formControlName="first" placeholder="First name">
        <input formControlName="last" placeholder="Last name">
      </div>
      <input formControlName="email" placeholder="Email">
      <button type="submit">Submit</button>
</form>

You can retrieve the structure

{
   name: {
      first: string,
      last: string,
   },
   email: string,
}

when doing form.value.

CodePudding user response:

I get the value as follows: this.myForm.get("property1").value

  • Related