Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to watch for valueChanges on a control within a formGroup under a dynamic formArray

i am new to Angular 2/4 and also to web development in general. I have this form that collects the information of variants of products in a purchase form. I have built a formArray of formGroups of variants as shown in below HTML.

<form [formGroup]="this.purchaseInvoiceItemVariantsForm" novalidate>
    <div formArrayName="variants">
        <div *ngFor="let variant of this.purchaseInvoiceItemVariantsForm.controls.variants.controls; let i = index">
            <div [formGroupName]="i">
                <md-input-container>
                    <input mdInput placeholder="Product Code"  formControlName="productBarcode" class="input--small" [readonly]="this.mode == 'view'">
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Color" formControlName="variant1" class="input--small" [readonly]="this.mode == 'view'" required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Size" formControlName="variant2" class="input--small" [readonly]="this.mode == 'view'" required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="MRP" formControlName="mrp" class="input--small" [readonly]="this.mode == 'view'">
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Purchase Price" formControlName="purchasePrice" class="input--small" [readonly]="this.mode == 'view'"
                        required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Sell Price" formControlName="sellPrice" class="input--small" [readonly]="this.mode == 'view'"
                        required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Quantity" formControlName="variantQuantity" class="input--small" [readonly]="this.mode == 'view'" required>
                </md-input-container>
                <md-input-container>
                    <input mdInput placeholder="Discount" formControlName="variantDiscount" class="input--small" [readonly]="this.mode == 'view'">
                </md-input-container>
                <button md-icon-button (click)="removeVariant(i)" color="warn" *ngIf="purchaseInvoiceItemVariantsForm.controls.variants.length > 1 && this.mode != 'view'"><md-icon>delete</md-icon></button>
            </div>
        </div>

Now once the user have added say 3 variants, i want to be able to listen to the valueChanges of the formControl "productBarcode" so that i can fetch the color and size details from the database.

Any suggestions how this can be achieved ?

thanks in advance!

Regards, Navin

like image 205
Navin Hotwani Avatar asked Apr 28 '17 10:04

Navin Hotwani


People also ask

How do I use ValueChanges in FormArray?

The ValueChanges is an event raised by the Angular forms whenever the value of the FormControl, FormGroup or FormArray changes. It returns an observable so that you can subscribe to it. The observable gets the latest value of the control. It allows us to track changes made to the value in real-time and respond to it.

Can FormArray contains FormGroup?

The FormArray is a way to Manage collection of Form controls in Angular. The controls can be FormGroup, FormControl, or another FormArray. Because it is implemented as Array, it makes it easier dynamically add controls.

How do I use FormGroup in FormArray?

We do not have a name to the FormGroup . The Index of the element is automatically assigned as the name for the element. Hence we use the [formGroupName]="i" where i is the index of the FormArray to bind the FormGroup to the div element. Finally, we add the controls using the formControlName directive.


1 Answers

We could do a version of the valueChanges, which starts listening when the variants-array length is a >= 3. Then we listen to each change in the barcode.

I assume you have a function where you add new controls to your variants array, we could implement it there:

addVariant() {
  // code here for adding control

  // check length   
  if(this.purchaseInvoiceItemVariantsForm.get('variants').length >= 3) {
    // iterate each object in array
    for(let val of this.purchaseInvoiceItemVariantsForm.get('variants').controls) {
      // listen to changes in each barcode, if change, do something!
      val.get('productBarcode').valueChanges.subscribe(data => {
      console.log(val.get('productBarcode').value)
      // do something!
      })
    }
  } 
}

Demo

like image 94
AT82 Avatar answered Nov 15 '22 03:11

AT82