0

i am trying to create the dynamic reactive form using angular i am able to loop it but it is displaying the exact way

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
  <div *ngFor="let dat of formData;let index = index;">
     <label for="{{dat.name}}">{{dat.name }}</label>
     <input type="text" id="{{dat.id}}" [formControlName]="dat.name" />  
    </div>


</form>
<button type="button"><button>

.ts

 registerForm: FormGroup;
  submitted = false;

  formData = [{ id: 'firstName', name: 'firstName' },
  { id: 'lastName', name: 'lastName' },
  { id: 'address', name: 'address' },
  { id: 'emailid', name: 'emailid' }
  ]


  constructor(private formBuilder: FormBuilder) {
    this.registerForm = this.formBuilder.group({
      formData: []
    });
   }

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

including the validation

below is my stackblitz url

https://stackblitz.com/edit/angular-awguej

5
  • 1
    The array you make can be a formArray angular.io/api/forms/FormArray . Commented Sep 27, 2018 at 6:18
  • could u once check my stack blitz and make changes ? Commented Sep 27, 2018 at 6:20
  • What you have there is no attempt to set the form controls to your form, so it won't work. Also, this would be a use for pure reactive forms. Check the documentation and attempt to do a reactive form with FormArray: angular.io/guide/reactive-forms If you encounter problems come back and ask :) Commented Sep 27, 2018 at 6:31
  • what do you ,mean by displaying in exact way? Commented Sep 27, 2018 at 6:36
  • Took me some while but posted it. Commented Sep 27, 2018 at 6:55

4 Answers 4

1

you can use this.formBuilder.array for this.

Stackblitz

component.html

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
    <div formArrayName="formData">
        <div *ngFor="let dat of registerForm.get('formData').controls;let index = index;" [formGroupName]="index">
            <label>{{dat.get('name').value }}</label>
     <input type="text" formControlName="name" />  
    </div>
<button type="submit">Submit</button>
  </div>
</form>
<button type="button" (click)="addNew()">Add</button>

component.ts

registerForm: FormGroup;
  submitted = false;

  constructor(private formBuilder: FormBuilder) {
    this.registerForm = this.formBuilder.group({
      formData: this.formBuilder.array([this.createNewGroup()])
    });
   }

   createNewGroup() {
    return this.formBuilder.group({
      id: ['id'], 
      name: ['name'] 
    })
  }

  addNew(){
    let formArr=this.registerForm.get('formData') as FormArray;
    formArr.push(this.createNewGroup());
  }

   onSubmit(){
    console.log(this.registerForm.value); 
   }
Sign up to request clarification or add additional context in comments.

Comments

1

I added a value cause you need an id to control an input field a name to set the label and a value to set the value. If you end up with a more dynamic way this will come in handy.

In your component you do:

formData = [{ id: 'firstName', name: 'firstName', value: '' },
  { id: 'lastName', name: 'lastName', value: '' },
  { id: 'address', name: 'address', value: '' },
  { id: 'emailid', name: 'emailid', value: '' }
  ]

  constructor(private formBuilder: FormBuilder) {
    let formGroups: FormGroup[] = []; 
    for(let i = 0; i < this.formData.length; i++){
      formGroups.push(this.formBuilder.group({
          id: this.formData[i].id,
          name: this.formData[i].name,
          value: this.formData[i].value,
      }));
    }
    this.registerForm = this.formBuilder.group({
        array: this.formBuilder.array(formGroups)
    })
   }

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

And in the html:

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
  <div formArrayName="array">
    <div *ngFor="let dat of registerForm.get('array').controls;let i = index;" [formGroupName]="i">
        <label>{{dat.get('name').value}} </label>
        <input type="string" id={{dat.value.id}} #input formControlName="value">
    </div>
  </div>
</form>

<button><button>

Comments

1

You can also add controls like this.

component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {

  registerForm: FormGroup;
  submitted = false;

  formData = [{ id: 'firstName', name: 'firstName' },
  { id: 'lastName', name: 'lastName' },
  { id: 'address', name: 'address' },
  { id: 'emailid', name: 'emailid' }
  ]


  constructor(private formBuilder: FormBuilder) {
    this.registerForm = this.formBuilder.group({
      list: this.formBuilder.array([])
    });
  }

  ngOnInit() {
    this.registerForm = this.formBuilder.group({
      list: this.formBuilder.array(
        this.formData.map(x => this.formBuilder.group({
          name: [x['name']],
          id: [x['id']]
        }))
      )
    })
  }

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

Component.html

<form [formGroup]="registerForm" (ngSubmit)="onSubmit()">
  <span formArrayName="list">
  <div *ngFor="let dat of registerForm.get('list').controls;let index = index;" formGroupName="{{index}}">
     <label for="{{dat.name}}">{{dat.name }}</label>
     <input type="text" id="{{dat.get('id').value}}" formControlName="name" />  
    </div>
  </span>
<button type="submit">button</button>
</form>

Comments

1

To complement Krishna's answer, if you want to create a formArray with data, you can create two functions.

//create a formGroup with the data or empy if not data
createNewGroup(data):FormGroup {
    return this.formBuilder.group({
        id: [data?data.id:null], 
        name: [data?data.name:null] 
    })
}

//And a function to create the form

createForm(formData):formGroup
{
    //create an array of FormGroup,
    //if data, with each element of data a newGroup
    //else an array with one element
    let group=formData? formData.map(d=>this.createNewGroup(d))
                      :[this.createNewGroup(null)]

    return this.formBuilder.group({
         formData: this.formBuilder.array(group)
       });
}

So, you can

this.registerForm=createform(this.formData) //create a form with data
this.registerForm=createform(null) //create a empty form

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.