Najam Us Saqib
Najam Us Saqib

Reputation: 3402

How to Get Value and Do Validation of Input inside *ngFor Angular

I have a Form (multiple Input fields) inside ngFor and i want to get values and validate them and add them to Users array to send it back to API.

  <form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
    <div *ngFor="let user of users">
      <div class="form-group">
          <label>First Name</label>
          <input type="text" formControlName="firstName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.firstName.errors }" />
          <div *ngIf="submitted && f.firstName.errors" class="invalid-feedback">
              <div *ngIf="f.firstName.errors.required">First Name is required</div>
          </div>
      </div>
      <div class="form-group">
          <label>Last Name</label>
          <input type="text" formControlName="lastName" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.lastName.errors }" />
          <div *ngIf="submitted && f.lastName.errors" class="invalid-feedback">
              <div *ngIf="f.lastName.errors.required">Last Name is required</div>
          </div>
      </div>
    </div>

    <div class="form-group">
        <button [disabled]="loading" class="btn btn-primary">Register</button>
    </div>
</form>

.ts

export class AppComponent  {
  users=[ 
    {id: 1},
    {id: 2},
    {id: 3}
  ]


  registerForm: FormGroup;
  submitted = false;
  constructor(private formBuilder: FormBuilder){
    this.registerForm = this.formBuilder.group({
      firstName: ['', Validators.required],
      lastName: ['', Validators.required]
    });
  }

  get f() { return this.registerForm.controls; };

  onSubmit() {
    this.submitted = true;
    // stop here if form is invalid
    if (this.registerForm.invalid) {
        return;
    }
    console.log(this.registerForm.value) // here i am getting value from last edited index.
  }
}

Edit: Stackblitz Exmple

Upvotes: 2

Views: 2961

Answers (2)

Chellappan வ
Chellappan வ

Reputation: 27419

You have to create array of FormGroup using users array.

Try this:

component.ts

 this.registerForm = this.formBuilder.group({
      userDetails: this.formBuilder.array(this.users.map(item=>{
       return this.createItem(item) 
      })),
  });

Since userDetails control is array of formGroup you don't need to use users array in html.

component.html

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
    <div formArrayName="userDetails" *ngFor="let item of registerForm.get('userDetails').controls; let i = index;">
        <div [formGroupName]="i">
            <div class="form-group">
                <label>First Name</label>
                <input type="text" formControlName="firstName" class="form-control"  />
                <div *ngIf="submitted && registerForm.controls['userDetails'].invalid" class="invalid-feedback">
                    <div>First Name is required</div>
                </div>
            </div>
            <div class="form-group">
                <label>Last Name</label>
                <input type="text" formControlName="lastName" class="form-control"  />
                <div *ngIf="submitted && registerForm.controls['userDetails'].invalid" class="invalid-feedback">
                    <div>Last Name is required</div>
                </div>
            </div>
        </div>
    </div>
    <div class="form-group">
        <button [disabled]="loading" class="btn btn-primary">Register</button>
    </div>
</form>

Example

Upvotes: 1

onik
onik

Reputation: 1631

you cant use a simple FormControl, for array values. formControl is only for a single value, so only the last edited value will be attached to them, you need to use https://angular.io/api/forms/FormArray for that

Upvotes: 0

Related Questions