Pushpinder Singh
Pushpinder Singh

Reputation: 63

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>

Upvotes: 5

Views: 4033

Answers (2)

Muhammed Aydogan
Muhammed Aydogan

Reputation: 660

When you do a patchValue with an object to a FormGroup which contains FormArrays inside, those values sometimes are not applied to FormArrays.
So I solved the issue by pushing items to FormArray one by one.

In my case:

this.form.patchValue(formObjectToPatch);

This was not working for the array: formObjectToPatch.someImportantProperty
I did this instead:

formObjectToPatch.someImportantProperty?.forEach(e => {
  (this.form.get('someImportantProperty') as FormArray<FormGroup>).push(
    this.fb.group({
      property1: [e.property1, [Validators.pattern('...')]],
      property2: [e.property2, [Validators.pattern('....')]],
    },
    { validators: this.someValidator} ))
});

Upvotes: 0

Pankaj Parkar
Pankaj Parkar

Reputation: 136144

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

Upvotes: 3

Related Questions