9

there are lots of blogs already posted for this error but none is specified for angular4.

I am adding and removing dynamic controls on the form

add controls to the form during intialization

    ngOnInit() {
    
        this.lienHolder = this._fb.group({
          emailAddress: ['', [Validators.required, Validators.email]],
          policyDetails: this._fb.array([
            this.initPolicyTemplate(),
          ])
        });
    
      }

     initPolicyTemplate() {
        return this._fb.group({
          policyNumber: ['', [Validators.required, Validators.pattern("(^[^0][A-Z]{1}[0-9]*$)")]],
          vinNumber: ['', [Validators.required, Validators.pattern('^[0-9]{6}$')]],
        });
      }

adding more control by calling this method

     addPolicyTemplate() {
        const control = <FormArray>this.lienHolder.controls['policyDetails'];
        control.push(this.initPolicyTemplate());
      }

removing controls from the form

      removePolicyTemplate(i: number) {  
        const control = <FormArray>this.lienHolder.controls['policyDetails'];
        control.removeAt(i);
      }

but when i build the code i get error like this

enter image description here

this is my html

      <div formArrayName="policyDetails">
            <div *ngFor="let _policy of lienHolder.controls.policyDetails.controls; let i=index">
              <div class="panel panel-default">
                <div class="panel-head">
                  <div class="glyphicon glyphicon-remove pull-right" *ngIf="lienHolder.controls.policyDetails.controls.length > 1" (click)="removePolicyTemplate(i)"></div>
                </div>
                <div class="panel-body">
                  <div [formGroupName]="i">
                    <address [policyGroup]="lienHolder.controls.policyDetails.controls[i]"></address>
                  </div>
                </div>
              </div>
            </div>
          </div>

I am not able to resolve this issue. i have followed this blog to come up with the dynamic control

UPDATE 1

when i changed my .ts code like this

    get DynamicFormControls() {
    
        return <FormArray>this.lienHolder.get('policyDetails');
      }

and the HTML code like this

     <div formArrayName="policyDetails">
            <div *ngFor="let _policy of DynamicFormControls.controls ; let i=index" style="position: relative">
              <add-policy-details [policyGroup]="lienHolder.controls.policyDetails.controls[i]"></add-policy-details>
              <div class="remove-btn" (click)="removePolicyTemplate(i)" *ngIf="lienHolder.controls.policyDetails.controls.length > 1">
              </div>
            </div>
          </div>

it was working, and i was able to compile the file in t he production mode, using the command

ng build --target=production --environment=prod

but from the past few days, i am facing the same error and not able to compile it in the production mode, i have not updated any of my application

node version - v6.11.1

npm version - 3.10.10

angular version - 4.0

dont know what exactly is causing the error.

Quethzel Diaz
  • 621
  • 1
  • 11
  • 26
Lijin Durairaj
  • 3,341
  • 11
  • 31
  • 50

8 Answers8

20

After digging deep found the solution here.When you are doing the production build,you have to use the problem can be fixed by giving your component a get method:

get formData() { return <FormArray>this.lienHolder.get('policyDetails'); }

and then in your template:

<div *ngFor="let _policy of formData.controls ; let i=index">

Hope this works for you

Vikhyath Maiya
  • 3,122
  • 3
  • 34
  • 68
14

I too faced the same issue on ng build but simply fixed with [],

*ngFor="let _policy of DynamicFormControls['controls'] ; let i=index"

use the above line instead of the below one

 *ngFor="let _policy of DynamicFormControls.controls ; let i=index"
Muthamizhchelvan. V
  • 1,241
  • 1
  • 17
  • 30
4
getArrayControls() {
    return (<FormArray>this.sampleForm.get('formArr')).controls;
  }

<div *ngFor="let elem of getArrayControls(); let i = index" [formGroupName]="i">
  <input formControlName="sampleElementOfArr">
</div>

UPDATE:

Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead

getArrayControls() {
    return (this.sampleForm.get('formArr') as FormArray).controls;
}

read more about Dynamically Creating Form Fields With FormArray

Dmitry Grinko
  • 13,806
  • 14
  • 62
  • 86
  • 4
    Can you add some words explaining your answer? – quicklikerabbit May 30 '19 at 21:07
  • 1
    Thank you for this code snippet, which might provide some limited, immediate help. A [proper explanation](https://meta.stackexchange.com/q/114762/349538) would greatly improve its long-term value by showing why this is a good solution to the problem and would make it more useful to future readers with other, similar questions. Please [edit] your answer to add some explanation, including the assumptions you’ve made. – CertainPerformance May 31 '19 at 04:44
  • when is providing the right answer not good enough? when it is posted in sadoverflow – Mukus Jul 08 '19 at 08:50
  • This is a great idea. I've just updated an answer a little bit. – Dmitry Grinko Aug 01 '19 at 01:08
3

In my case problem was I mentioned the return type of function as FormArray. I removed the return type now my getter method looks like this

 get eventExtraDetailsArray(){
    return this.addEventExtraForm.get('regDetails') as FormArray;
  }

and in the HTML I modified the code to something like this

<div formArrayName="regDetails">
          <div *ngFor="let eventCharge of addEventExtraForm['controls'].regDetails['controls']; let regIdx = index"
            [formGroupName]="regIdx">
 </div>
</div>

Now the production build works fine.

Dan Patil
  • 771
  • 6
  • 15
2

Square brackets [] and Single quotes ['controls'] in this case, should fix the issue. Also when you have to iterate over 2 times controls. Here is a good answer to this kind of topic: JavaScript property access: dot notation vs. brackets?.

This wasn't working for me:

let brand of productsForm.controls.brands.controls; ...

changing it to:

let brand of productsForm['controls'].brands['controls']; ...

removed the error.

Square bracket notation allows access to properties containing special characters and selection of properties using variables

k.vincent
  • 3,743
  • 8
  • 37
  • 74
2

Yeah it's a strange bug although the class FormGroup contain a filed named controls
But you can try this out:
Inside a loop:
<div *ngFor="let _policy of formData['controls'] ; let i=index">

When you want to get a specific control:

<div *ngIf="form.get('myCntrol').touched && form.get('myCntrol').errors"></div>
SlimenTN
  • 3,383
  • 7
  • 31
  • 78
0

this issue is addressed on github. easiest way out is using yourFormArray['controls'] instead of yourFormArray.controls in *ngFor, or if you have a get accessor you can access the controls using that.

Anand Bhushan
  • 765
  • 8
  • 18
0

You can use the push and removeAt methods:

// to push form group
const firstArray = this.invoiceForm.get('invoiceList') as FormArray;
const secondArray = firstArray.controls[j].get('packingList') as FormArray;
secondArray.push(this.initPackingList());

// to remove form group
const firstArray = this.invoiceForm.get('invoiceList') as FormArray;
const secondArray = firstArray.controls[j].get('packingList') as FormArray;
secondArray.removeAt(deletingIndex);
Max
  • 965
  • 1
  • 10
  • 28