How to detect changes in form control array in Angular 4?
Asked Answered
F

2

8

I am working on Angular 4 project. I have a requirement to detect the changes of form control array. e.g. I have a form control array named providers, how to detect its changes?

export class CustomFormArray {
 public form: FormGroup;

 constructor(private _fb: FormBuilder) {
      this.form = _fb.group({
           providers: _fb.array([])
      });
  }
} 
Froufrou answered 7/11, 2017 at 5:26 Comment(4)
You need to register the element inside of providers array as another group in order to detect it.Goodygoody
can you please explain it?Froufrou
What are the element of providers ?Goodygoody
It build on run time, its not possible to register firstFroufrou
W
16

FormArray extends AbstractControl so it has valueChanges property which emits chanes.

this.form = this.fb.group({
  providers: this.fb.array([]),
});
(this.form.get('providers') as FormArray).push(new FormControl('', Validators.required));
(this.form.get('providers') as FormArray).push(new FormControl('', Validators.required));

(this.form.get('providers') as FormArray).valueChanges.subscribe(values => {
  console.log(values);
});

In your template:

<input *ngFor="let field of form.controls.providers.controls;" [formControl]="field">

The values in subscribe will return a array with value of each input field when any of changes(grammatically or from UI).

In case of if there are FormGroup in FormArray nothing changes. just use following component code.

(this.form.get('providers') as FormArray).push(this.fb.group({
      'name': '',
      'age': ''
    }));

and template will be:

<div *ngFor="let field of form.controls.providers.controls;" [formGroup]="field">
  <input formControlName="name" placeholder="name">
  <input formControlName="age" placeholder="age">
</div>

here is plunker

Womanlike answered 7/11, 2017 at 6:30 Comment(7)
I was try this . It works fine in the case of form control but it doesn't detect changes in form control array. Am surprise why?Froufrou
I updated my answer now valueChanges is on FormArray and it's working perfectly fine. Could you explain more about your problemWomanlike
Yes, I will explain, I have a providers form control array. on run time it contains a record of a provider on index 0. when I change the provider. Its remove the index and recreate it with new provider detail. But my problem is that valueChanges not detect changes in this array. I also tried your updated code. But same problem exist.Froufrou
Please update your question with more code. May be there are some problem in how you are doing this.Womanlike
I had solved it myself. There is problem that I remove and add form control array whenever the value change. That's why it doesn't detect changes.Froufrou
If valueChanges callback is not working you can trigger it manualy using this.form.controls.providers.updateValueAndValidity({ onlySelf: false, emitEvent: true });Individualist
What can I do to have the subscription emitting only the control that was updated/changed? I'd conform to isolating only the emitting group ...Ramires
O
2

Is similar as how you do it for normal form group. Whenever you initialize form group of your form array, just emit/subscribe change event your form group of your form array.

here is the sample.

 export class CustomFormArray {
     public form: FormGroup;

     constructor(private _fb: FormBuilder) {
          this.form = _fb.group({
               providers: _fb.array([])
          });

      this.providers.push(this.createprovidersFormGroup())
      }

    createprovidersFormGroup(){
          let form = this._formBuilder.group({
                         abc: "abc"


                     });

              form.valueChanges.subscribe(data => {
                  console.log('Form changes', data)
              });

         return form;
        } 
Overflight answered 7/11, 2017 at 6:16 Comment(1)
I already try this out. But valueChanges not work in case of form control arrayFroufrou

© 2022 - 2024 — McMap. All rights reserved.