0

I have simple angular form to save user input. Where user can click on Add More button to add as many row they want which is working fine.

And I want that if testData (which defined on component) have length then this testData should be already in-place on component init, but I don't know how to do this.

component.ts

import { Component, VERSION, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
 productForm: FormGroup;
 testData = [{ "name": "test-1", "age": "24" }, { "name": "test-2", "age": "32" }, { "name": "Test-3", "age": "20" }]
 constructor(private fb: FormBuilder) {}

 ngOnInit() {
   this.addRowData();
   this.productForm = this.fb.group({
   stepName: 'Field Data',
   fieldData: this.fb.array([]) ,
  });
 }

 fieldData() : FormArray {
  return this.productForm.get("fieldData") as FormArray
 }

 newFieldData(): FormGroup {
  return this.fb.group({
   name: '',
   age: '',
  })
 }

 addRowData() {
   this.fieldData().push(this.newFieldData());
 }

 removeRowData(i:number) {
   this.fieldData().removeAt(i);
 }

 onSubmit() {
   console.log(this.productForm.value);
 }
}

index.html

<table formArrayName="fieldData">
    <tr *ngFor="let data of fieldData().controls; let i=index" [formGroupName]="i">
      <td>
          Name :
          <input type="text" formControlName="name" class="form-control">
      </td>
      <td>
          Age:
          <input type="text" formControlName="age" class="form-control">
      </td>
      <td>
          <button (click)="removeRowData(i)" class="btn btn-danger">Remove</button>
      </td>
    </tr>
  <tr>
    <th width="150px"><button type="button" (click)="addRowData()" class="btn btn-primary">Add More</button></th>
  </tr>
</table>

2 Answers 2

1

You are already half way done just modify your newFieldData() method and pass default data param and check if data exist set data else set empty value which you are already doing.

 // passing data param with default value null 
 newFieldData(data = null): FormGroup {
   return this.fb.group({
     name: data ? data.name : '', // here you can set value if exists else empty
     age: data ? data.age : '',
 });
}

Now all you need to add this piece of code in you ngOnInit method

if (this.testData.length) {
  this.testData.map((data) => this.fieldData().push(this.newFieldData(data)));
}

Thats it, chekcout working DEMO

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

Comments

1

I created a bug-fixed sample for you on Stackblitz.

Try this:

app.component.ts

import { Component,OnInit } from '@angular/core';
import { FormGroup, FormBuilder, FormControl,Validators,FormArray } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
 productForm: FormGroup;
 testData = [{ "name": "test-1", "age": "24" }, { "name": "test-2", "age": "32" }, { "name": "Test-3", "age": "20" }]
 constructor(private fb: FormBuilder) {
   this.productForm = fb.group({
     fieldData: this.fb.array([])
   });
 }

 ngOnInit() {
  this.initialize();
 }

get fieldData(): FormArray {
  return this.productForm.get("fieldData") as FormArray;
}

newFieldData() : FormGroup {
  return this.fb.group({
    name: [""],
    age: [""],
  })
}

addNewField(){
  this.fieldData.push(this.newFieldData())
}

removeField(i:number) {
  this.fieldData.removeAt(i);
}

onSubmit() {
  console.log(this.fieldData.value);
}

initialize() {
  if( this.testData.length > 0 ) {
    this.testData.forEach((item) => {
       this.fieldData.push(
         this.fb.group({
            name: [item.name],
            age: [item.age],
          })
        );
      });
    }
  }

}


// angular form is group of controls

app.component.html

<div class="main-container">
  <form [formGroup]="productForm">
    <div formArrayName="fieldData" class="form-array">
      <div *ngFor="let data of fieldData.controls; let i=index">
        <div [formGroupName]="i" class="form-group">
          <div class="name-container">
            <label for="name">Name:</label>
            <input type="text" formControlName="name">
          </div>
          <div class="name-container">
            <label for="name">Age:</label>
            <input type="text" formControlName="age">
          </div>
          <button class="btn btn-danger" (click)="removeField(i)">Remove</button>
        </div>
      </div>
    </div> 
  </form>
  <p>
    <button class="btn btn-success" type="button" (click)="addNewField()">Add</button>
  </p>
</div>

3 Comments

Sorry @ng-hobby, but i need that testData in same create form.
Ok, I updated my answer befor you said. ;) Check it, I'll try to provide a sample for you
I'll edir my answer & created a sample also on Stackblitz. Check it out.

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.