Search code examples
angulartypescriptangular-reactive-forms

How to use patchValue inside dynamic FormArray in Angular?


In first case (Working DEMO link) patchValue() is able to manipulate the select drop-down menu in which reactive FormGroup() only consists FormControl() and in second case I have to use the same functionality of when user adds input its value shows directly selected on select-dropdown; but this time I have to set value using patchValue() inside FormArray(), which is not working as expected. How to make it work inside FormArray()?

FIRST CASE

app.component.ts

export class AppComponent {

      entityInfoForm: FormGroup;
    
      items = ['Mobile', 'Home', 'School'];
      
      constructor() {
        this.entityInfoForm = new FormGroup({
           name: new FormControl(""),
           control: new FormControl("")
        });
      }
    
      addCustom(v: string) {
        this.items.push(v);
        this.entityInfoForm.patchValue({control: this.items[this.items.length - 1]});
      }

      onSubmit() {
         console.log(this.entityInfoForm);
      }

   }

app.component.html

<form role="form" [formGroup]="entityInfoForm" (ngSubmit)="onSubmit()">

   <div class="form-group">
       <label for="usr">Name</label>
       <input type="text" class="form-control" id="name" formControlName="name" >
   </div>
 
    <div class="form-group">
       <select formControlName="control">
         <option *ngFor="let item of items" [ngValue]="item">{{item}}</option>
       </select>
   </div>

   <button type="submit">Submit Form</button>

</form>

<input type="text" #custom>
<button (click)="addCustom(custom.value)" >Add</button>

SECOND CASE Note: Here we use Dynamic FormArray, multiple can be made in this case

app.component.ts

export class AppComponent {

  entityInfoForm: FormGroup;

  items = ['Mobile', 'Home', 'School'];

  constructor() {
    this.entityInfoForm = new FormGroup({
       name: new FormControl(""),
       contact: new FormArray([
           new FormGroup({
                type: new FormControl(''),
                contact: new FormControl('')
           })
       ])
    });
  }

  addCustom(v: string) {
    this.items.push(v);
    this.entityInfoForm.patchValue({type: this.items[this.items.length - 1]});
  }

  onSubmit() {
     console.log(this.entityInfoForm);
  }
}

app.component.html

Name
       <div>
          <select class="form-control formControlName="type">
              <option *ngFor="let item of items" [ngValue]="item">{{item}}</option>
          </select>
       </div>
       
   </div>


</form>

<input type="text" #custom>
<button (click)="addCustom(custom.value)" >Add</button>

Solution

  • To patch value on a specific element, you should first get hold of a specific formArray element first using .get method. And then push the value into the array.

    this.entityInfoForm
      .get(['contact', 0])
      // .get('contact.0') // <-- alternative
      ?.patchValue({ type: this.items[this.items.length - 1] });
    

    Working Stackblitz