0

Below is my FormArray, I would like to update one input based on the value changes on another input. Whenever user changes the product, the service will get the price and taxPercent, which needs to be patched for that index in the form array and when the quantity is added, i would like to patch the totalAmount. This was easy when it's just a formControlElements by subscribing to respective valueChanges and path the respective fields. How can I do the same in FormArray?

<div formArrayName="products" *ngFor="let product of productsArray.controls; let i=index">
      <div [formGroupName]="i">
          <div class="form-row">

              <div class="form-group col-md-4">
                  <label for="product">Product</label>
                  <select formControlName="pdt"  class="form-control" >
                      <option [value]="pdt.productPriceId" *ngFor="let pdt of productPrice">{{pdt.productName}}  -  {{pdt.size}}</option>
                  </select>
              </div>

              <div class="form-group col-md-1">
                <label for="price">Price</label>
                <input type="text" class="form-control" formControlName="price" id="price">
              </div>
              <div class="form-group col-md-1">
                <label for="taxPercent">Tax %</label>
                <input type="text" class="form-control" formControlName="taxPercent" id="taxPercent">
              </div>

              <div class="form-group col-md-1">
                <label for="quantity">Qty</label>
                <input type="text" class="form-control" formControlName="quantity" id="quantity">
              </div>

              <div class="form-group col-md-1">
                <label for="totalAmount">Amt</label>
                <input type="text" class="form-control" formControlName="totalAmount" id="totalAmount">
              </div>

            <div class="form-group col-md-1">
                <span>
                  <button class="btn btn-primary" (click)=addProduct()>Add</button>
                </span>
            </div>
            <div class="form-group col-md-1">
              <span>
                <button class="btn btn-primary" (click)=removeProduct(i)>Remove</button>
              </span>
          </div>
        </div>
      </div>
    </div>

My Value Changes Subscription for a FormControl looks like below. But I'm not sure how to do the same for FormArray

this.billingForm.get('products[0].pdt').valueChanges.subscribe(
      (value) => {

          console.log(value);
          let taxPercentVal: Number = 0;
          let priceVal: Number = 0;
          this.productPrice.forEach(function (val) {
            if(value == val.productPriceId)
            {
              taxPercentVal = val.taxPercent;
              priceVal = val.price;
            }
          });

          this.billingForm.patchValue({
            products: {
              taxPercent: taxPercentVal,
              price: priceVal,
              quantity: '',
              totalAmount: '' 
            }
          })



      }
    );



    this.billingForm.get('products.quantity').valueChanges.subscribe((value) => {
          console.log(value);
          let taxPer = this.billingForm.value.products.taxPercent;
          console.log(taxPer);
          let pr = this.billingForm.value.products.price;
          console.log(pr);
          let qty = value;
          console.log(qty);
          let totAmt = (pr * qty) + ((pr * qty) / taxPer);
          console.log(totAmt);
          this.billingForm.patchValue({
            products: {
              totalAmount: totAmt
            }
          })
    })

1 Answer 1

3

you might want to add a function on your change event. Something like below:

<div class="form-group col-md-4">
                  <label for="product">Product</label>
                  <select formControlName="pdt"  class="form-control" **(change)="onChange($event)"** >
                      <option [value]="pdt.productPriceId" *ngFor="let pdt of productPrice">{{pdt.productName}}  -  {{pdt.size}}</option>
                  </select>
</div>

You should be able to capture the new product there and can update your rest of the fields using data binding. Hope it helps!

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

4 Comments

Thank you so much. Can you also add a code snippet for onChange method. I'm not sure how to do the data binding for FormArray elements.
I am afraid i cannot give you the exact function as I dont have your complete code. But I can give you logic of what needs to be done. Write onChange(event) function in your component.ts file. You can pass the product object to onChange function, so now you have which product is selected in your controller(component.ts). Once you know which new product is selected, the only thing remaining is to update the view which you can achieve by simple data-bindings. If you want to understand data-binding better, following article might help: angular.io/guide/form-validation
It worked. Thank you. PatchValues still work with formArrays as well
you solution is not working with form array. if I have 2 or 3 select option then once I change the value select option, other select option also changed.

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.