Search code examples
javascriptangulartypescriptrxjsangular-forms

Form array of form group , get changes for exact specific control - angular


I have my form structure as below ..

this.myForm =  this.formBuilder.group({
 control1: this.formBuilder.control({value: ''}),
 groupcontrol1: this.formBuilder.array({ this.addGroupControl() });
});


addGroupControl(): FormGroup {
   return this.formBuilder.group({
     recurringControl1: this.formBuilder.control({value: ''}),
     recurringControl2: this.formBuilder.control({value: ''}),
     recurringControl3: this.formBuilder.control({value: ''}),
    });
  });

I have a button in html , to add groups to this array , which will look like this

addGroups() {
    (<FormArray>this.myForm.get('groupcontrol1')).push(this.addGroupControl());
  }

This is my form in html

<form [formGroup]="myForm" (ngSubmit)="onSubmit()">
  <label> control1    </label>
  <input type="text"/>
  <button type="button" (click)="addGroups()"> Add Groups</button>
  <accordion>
    <accordion-group formArrayName="groupcontrol1"
      *ngFor="let group of myForm.get('groupcontrol1').controls; let i = index">
      <div accordion-heading>
        Group Control {{ i + 1 }}
      </div>
    <div [formGroup]="i">
      <input formControlName="recurringControl1" />
      <input formControlName="recurringControl2" />
      <input formControlName="recurringControl3" />
    </div>
    </accordion-group>

  </accordion>
</form>

now for each of the recurring control I need to get notified which recurring control value got changed in which form , for this I am using below code

 merge(
      ...this.myForm
        .get('groupcontrol1')
        .controls.map((eachGroup, index: number) =>
          eachGroup.controls.recurringControl1.valueChanges
           .pipe(map((value) => ({ rowIndex: index, control: eachGroup, data: value })))
        )
    ).subscribe((changes) => {
      console.log(changes);
    });

using above code , I am getting value change of recurringControl1 from 1st form grous , not other form groups . basically only when row index is 0 , only getting that value

any modification or suggestion on above code to get exactly which control out of the 3 recurring controls value changed


Solution

  • I think your problem is creating new entries of FormGroups in groupcontrol1 after subscribing to it changes.

    I think you need something like this:

    export class AppComponent {
      myForm;
      myArray;
      trigger = new BehaviorSubject(null);
      constructor(private fb: FormBuilder) {
        this.myForm = this.fb.group({
          control1: fb.control('defaultvalue'),
          groupcontrol1: fb.array([this.addGroupControl()])
        });
    
        this.myArray = this.myForm.get('groupcontrol1');
        this.myArray.push(this.addGroupControl());
    
        this.trigger
          .pipe(
            switchMap(t => {
              const obs = this.myArray.controls.map((c, k) => {
                return c.valueChanges.pipe(map(data => ({ data, i: k })));
              });
              return merge(...obs);
            })
          )
          .subscribe(x => {
            console.log(x);
          });
      }
    
      addGroupControl(): FormGroup {
        return this.fb.group({
          recurringControl1: this.fb.control('1'),
          recurringControl2: this.fb.control('2'),
          recurringControl3: this.fb.control('3')
        });
      }
    
      newRow() {
        this.myArray.push(this.addGroupControl());
        this.trigger.next(null);
      }
    }
    

    https://stackblitz.com/edit/angular-ivy-faqvw9?file=src/app/app.component.ts