quma
quma

Reputation: 5733

Angular 5 FormArray

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>
   ...

Upvotes: 3

Views: 7410

Answers (4)

almcaffee
almcaffee

Reputation: 112

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.

Upvotes: 0

Abhijit Kar ツ
Abhijit Kar ツ

Reputation: 1732

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.

Upvotes: 1

Alex Ananjev
Alex Ananjev

Reputation: 279

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 :)

Upvotes: 1

Ricardo
Ricardo

Reputation: 2487

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

Upvotes: 5

Related Questions