5

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>

2 Answers 2

3

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

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the answer but it works only for the first FormArray, since multiple forms like this can be created so how can I make sure the input which i'm entering changes of that particular select. Is there a way I can pass index of the select with addCustom()?
@PushpinderSingh the whole idea is you can pass index, for eg .get(['contact', index]) and you can patchValue. And yes, it would be explicit
if you add a formGroup in a FormArray, you know that the last is formArray.controls.length-1, so you can: formArray.push(...);form.get('contact.'+formArray.length-1).patchValue(..)
0

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} ))
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.