3

I have this FormArray in my Angular 5 / Angular Material application:

this.form = new FormGroup({    
    customerNumberContainers: new FormArray([
      new FormGroup({
        contactTenant: new FormControl('', [Validators.required, Validators.minLength(2)]),
        customerNumber: new FormControl('', [Validators.required, Validators.minLength(2)])
        }),
    ]),
...

Actually I don't know how to run through this FormArray. I have tried this on

<form [formGroup]="form" (ngSubmit)="onSubmit()">
    <div formGroupName="customerNumberContainers">          
        <div *ngFor="let customerNumberContainer of form.controls['customerNumberContainers']; index as i">
            <mat-input-container class="full-width-input" style="min-width:100px;">
                 <input matInput placeholder="Tenant" formControlName="customerNumberContainer[i].contactTenant">
            </mat-input-container> 
            <mat-input-container class="full-width-input" style="min-width:100px;">
                 <input matInput placeholder="Customernumber" formControlName="customerNumberContainer[i].customerNumber">
            </mat-input-container> 
        </div>
    </div>
   ...
1
  • Didi you think about creating a custom component implementing ControlValueAccessor to handle the array modifications ? Commented Mar 2, 2018 at 13:17

4 Answers 4

5

actually how you should do it is like this:

have a method that return your control array

get customerNumberContainers(): FormArray {
    return this.form.get("customerNumberContainers") as FormArray;
    } 

you going to use the variable i to manage the form groups inside your array

<form [formGroup]="form" (ngSubmit)="onSubmit()">
<div formArrayName="customerNumberContainers">          
    <div *ngFor="let customerNumberContainer of customerNumberContainers.controls; index as i" [formGroupName]="i">
        <mat-input-container class="full-width-input" style="min-width:100px;">
             <input matInput placeholder="Tenant" formControlName="contactTenant">
        </mat-input-container> 
        <mat-input-container class="full-width-input" style="min-width:100px;">
             <input matInput placeholder="Customernumber" formControlName="customerNumber">
        </mat-input-container> 
    </div>
</div>

...

you can create add methods and delete methods to manage the formgroups inside your array

add(data?: any) {
   /// data is to set up values to your internal form (useful for edition)
        this.customerNumberContainers.push(this.fb.group({
         }))
    }

    remove(index: number) {
        this.customerNumberContainers.removeAt(index)
    }

I hope this help you

greetings

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

Comments

1

Change your

<div *ngFor="let customerNumberContainer of form.controls['customerNumberContainers']; index as i">

To:

<div *ngFor="let item of getControls(); let i = index">

And in your .ts file add:

getControls() {    
 const fa = this.form.get('customerNumberContainers') as FormArray;  return 
 fa.controls; 
}

End result should be:

<form [formGroup]="form" (ngSubmit)="onSubmit()">
    <div formArrayName="customerNumberContainers">          
        <div *ngFor="let item of getControls(); let i = index">
           <div [formGroupName]="i">
            <mat-input-container class="full-width-input" style="min-
               width:100px;">
                 <input matInput placeholder="Tenant" formControlName="contactTenant">
            </mat-input-container> 
            <mat-input-container class="full-width-input" style="min-width:100px;">
                 <input matInput placeholder="Customernumber" formControlName="customerNumber">
            </mat-input-container> 
        </div>
    </div>...

Hope this helps :)

1 Comment

You can directly use form.get('customerNumberContainers').controls in the template. the getControls() function is useless
1

Have a look at the working demo

StackBlitz: Demo

Explanation:

  1. Quite a few things needs to happen to work with Form Array in Angular. Refer the Aligator.io blog post.
  2. When used without square bracket: formControlName="value", value is meant as a string.
  3. When Square brackets are used: [formControlName]="customerNumberContainer[i].contactTenant", then variables are accepted.

Comments

0

Are you going to have multiple formGroups in the form array?

this.form = new FormGroup({    
  customerNumberContainers: new FormArray([
    new FormControl('', [Validators.required, Validators.minLength(2)]),
    new FormControl('', [Validators.required, Validators.minLength(2)])
  ])
});

This is how it should look if not. And remember when changing the value of a form array use a constant

const arr = <FormArray>this.form;

Then you can push, etc...

arr.push(new FormControl(''));

Some form array functions won't work if you dont.

Comments

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.