1

I started coding on Angular 9 not quite long ago and am creating a Reactive Form that has form controls which are being added dynamically via the FormArray Abstract, but whenever i try to loop through the value property of the formArray control, i get this unbelievably weird error i have been trying to figure out for almost 12 hours. This error doesn't come when i have just one array entry under the value node. Could someone point out what am doing wrong?

Here is the error:

enter image description here

This is my form builder:

this.quotationForm = this.fb.group({
      customerId : new FormControl('', Validators.required),
      customerName : new FormControl(),

      'contact' : this.fb.group({
        customerAddress : new FormControl('',Validators.required),
        customerPhone : new FormControl('', Validators.required),
        customerEmail : new FormControl('', Validators.email),
      }),

      'itemsgroup' : new FormArray(
        [
          this.fb.group({
            item : '',
            quantity : '',
            amount : ''
          })
        ],{validators : Validators.required}),

      currency : new FormControl(),
      discount : new FormControl(),
      taxRate : new FormControl(),
      taxAmount : new FormControl(),
      purchase : new FormControl(),
      note : new FormControl(),
      total :new FormControl(),
      ref : new FormControl(),
      tailor : this.usrId,
      datecreated : new FormControl(this.model, Validators.required),
});

Here is the function call from my component:

 getSelectedItemsSum(){
    let quotesTotal = 0;
    let itemsgroupAmt = 0;
    let itemsgroupQty = 0;
    let itemsgroup = this.itemsgroup();

    if(itemsgroup.touched == true && itemsgroup.status !== 'INVALID'){
      if(itemsgroup.value.length > 1){
        console.log(itemsgroup.value);
        for(let i = 0; i <= itemsgroup.value.length; i++){

          if((itemsgroup.value[i].amount != '' || itemsgroup.value[i].amount != 0) && (itemsgroup.value[i].quantity != '' || itemsgroup.value[i].quantity != '')){
            itemsgroupAmt += itemsgroup.value[i].amount;
            itemsgroupQty += itemsgroup.value[i].quantity;
          }
        }

        quotesTotal = (itemsgroupAmt * itemsgroupQty);
      }else{
        if((itemsgroup.value[0].amount != '' || itemsgroup.value[0].amount != 0) && (itemsgroup.value[0].quantity != '' || itemsgroup.value[0].quantity != 0))
          quotesTotal = (parseInt(itemsgroup.value[0].amount) * parseInt(itemsgroup.value[0].quantity));
      }
    }else return;

    console.log(itemsgroup)
  }

This is the itemsgroup() function

itemsgroup() : FormArray{
    return this.quotationForm.get('itemsgroup') as FormArray;
  }

A code snippet of my html template:

<div formArrayName="itemsgroup" class="row row-xs mb-2">
                <div *ngFor="let group of itemsgroup().controls; let i = index" class="col-xl-12">
                  <div [formGroupName]="i" class="row row-xs mb-2 relative">
                    <div class="col-md-4">
                      <input type="text" formControlName="item" placeholder="Item {{i + 1}}" class="form-control" required>
                    </div>
                    <div class="col-md-4">
                      <input 
                        type="number" 
                        formControlName="quantity" 
                        placeholder="Quantity {{ i + 1 }}" 
                        min="1" step="1" value="1"
                        class="form-control" required>
                    </div>
                    <div class="col-md-4">
                      <input 
                        (change)="getSelectedItemsSum()"
                        type="number" 
                        formControlName="amount" 
                        placeholder="Amount {{ i + 1 }}"  
                        class="form-control" required>
                    </div>
                    <button 
                      (click)="removeItemGroup(i)"
                      *ngIf="(i >= 1)"
                      mat-fab 
                      mat-stroked-button 
                      color="primary" 
                      matTooltip="Delete Item Group" 
                      style="position:absolute;right:7px;top:17px;width:22px;height:22px;">
                      <i style="position:absolute;top:5px;left:8px">*</i>
                    </button>
                  </div>
                </div>
              </div>

Here is my form (truncated tho): enter image description here

3
  • What is the result of itemgroup? Commented Mar 13, 2020 at 5:31
  • Can you write (copy paste) the code instead of taking a picture? It makes it easier to read, and test ourselves. Cheers Commented Mar 13, 2020 at 5:56
  • i have done that now Commented Mar 13, 2020 at 13:31

2 Answers 2

4

Please change let i = 1 instead of let i = 0 because you are using less-than equal i<=itemgroup.value.length in for loop.

Change your loop conditions like below,

for (let i = 1; i <= itemgroup.value.length; i++)
{    

// your code

}

or

for (let i = 0; i < itemgroup.value.length; i++)
{    

  // your code

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

3 Comments

I think this is exactly what am doing
I think i understand you now. I'll do the edits and try again
this suggestion for(let i = 0; i < itemsgroup.value.length; i++) solved my problem. Thank you!
0
  1. please change name of method itemsgroup(), your method and formArray have same name.
  2. in template change <div *ngFor="let group of itemsgroup().controls; let i = index" class="col-xl-12"> to

    <div *ngFor="let group of quotationForm.get('itemsgroup').controls; let i = index" class="col-xl-12">
    

Unrelated Suggestion

Instead of having a change event on controls in templates. You should rather make use of valueChanges observable provided by 'FormControl', that way you'll be doing it more "Angular way".

5 Comments

It's hard to know the "Angular Way" when you're still new to it you know. Thanks for your suggestion,
identifier "controls" is not defined. 'AbstractControl' does not contain such a member
Please post your code where you are building the form quotationForm
is it just my laptop or the valueChanges() fires twice, onBlur and onChange?
i'll edit my question and add the code for the formBuilder

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.