angulardata-bindingnested-forms

Angular - two way binding in nested formgroup


I have created a nested formgroup using builder. Addition of data in database is successful but when I am trying to map data back to same form, not sure how to achieve it. I thought two way binding will help but facing many issues. Can anyone please suggest how to achieve two way binding in nested formgroup.

ngOnInit(){

this.myForm = this._fb.group({
  name: ['', [Validators.required, Validators.minLength(5)]],
  addresses: this._fb.array([
      this.initAddress(),
  ]),
  search:['']
});
  }

  initAddress() {
return this._fb.group({
    street: ['', Validators.required],
    postcode: ['']
});
  }

  addAddress() {

const control = <FormArray>this.myForm.controls['addresses'];
control.push(this.initAddress());
  }

customer interface is:

export class Customer {
_id?: string;
name: string;
addresses: Address[];
}

export interface Address {
street: string;
postcode: string;
}

I have fetched particular data from database. Now I would like to use same component (used for addition) for update purpose.

template is:

<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm.value)">

<div class="form-group">
    <label>Name</label>
    <input type="text" formControlName="name">
    <small *ngIf="!myForm.controls.name.valid" class="text-danger">
        Name is required (minimum 5 characters).
    </small>
</div>

<div formArrayName="addresses">
    <div *ngFor="let address of myForm.controls.addresses.controls; let i=index">
        <div>
            <span>{{ applicant[i] }}</span>
            <!-- <span *ngIf="myForm.controls.addresses.controls.length > 1" (click)="removeAddress(i)">
            </span> -->
        </div>
        <div [formGroupName]="i">
            <app-address [group]="myForm.controls.addresses.controls[i]"></app-address>
        </div>
    </div>
    <button type="add" (click)=" addAddress(i)">Add address</button>
</div>

<p>Form value: {{ myForm.value | json }}</p> 
<br>
<p>Form value: {{ myForm.status | json }}</p>

<button type="submit" [disabled]="!myForm.valid">Submit</button>
<button type="reset">Reset</button>

</form>

Address component template:

<div [formGroup]="adressForm">
<div class="form-group col-xs-6">
  <label>street</label>
  <input type="text" class="form-control" formControlName="street">
  <small [hidden]="adressForm.controls.street.valid" class="text-danger">
      Street is required
  </small>
</div>
<div class="form-group col-xs-6">
  <label>postcode</label>
  <input type="text" class="form-control" formControlName="postcode">
</div>
</div>

Solution

  • Simply call the setValue or patchValue methods on the FormGroup and pass it the value you want your form to have. The object should obviously match the FormGroup's structure.

    this.myForm.patchValue({
        name: 'some name',
        search: 'some value',
        addresses: [{
            street: 'some street',
            postcode: '11111'
        }]
    })