0
votes

Angular 9 : Used formarray without form tag in html content but now need to add validations and added form tag to the html component, now code does not work!

Used a formarray to dynamically generate a row of controls(textbox and textarea) on button click;The html component did not have form tag and this was achieved by first creating a formarray:

requirement=new FormArray([]);

and within the html component added the following:

    <tr let req of requirement.controls let i=index>
<td>
<input type="number" name="Req#" [(NgModel)]="reqno"/>
</td>
<td>
<textarea type="text" name="Req" [(NgModel)]="req"></textarea>
</td>
:
:
:
</tr>

and on button click applied the following code:

this.requirement.push(new FormControl(''));

This helps in generating dynamic controls but with this no validations can be performed and so added the form tag to the html component and add formControlName instead of NgModel and instead of the above typescript code: declare the formarray as follows:

public requirement:FormArray;

and initialize the same on ngOnInit():

this.requirement=new FormArray([
new FormGroup({

reqno:new FormControl('');
req:new FormControl('');

})
]);

after changing this the Ngif and NgFor does not work.Could anyone help out.

1
What error message do you get? - Lynx 242
@lynx 242 : ERROR:formControlName must be used with a FormGroup directive.You will want to add a FormGroup directive and pass it an existing FormGroup instance - This is what is got from the console. - Alesha Developer

1 Answers

0
votes

@AleshaDeveloper, FormArray are ReactiveForms, [(ngModel)] is Template driven form

Well, make a function that return a formGroup. You can use Validators in your function

newFormGroup()
{
  return new FormGroup({
    reqno:new FormControl(''),
    req:new FormControl('',Validators.required)
  })
}

And use it, in ngOnInit to create the form and in a function to add the element

ngOnInit()
{
    this.requirement=new FormArray([this.newFormGroup()])
}

addGroup()
{
   this.requirement.push(this.newFormGroup())
}

We create an auxiliar function, that return the formGroup of the formArray at index(*)

  groupAt(index)
  {
    return this.requirement.at(index) as FormGroup
  }

Now, we can use this function creating a formGroup for each row

<tr *ngFor="let group of requirement.controls;let i=index" [formGroup]="groupAt(i)">
<td>
  <input type="number" formControlName="reqno"/>
</td>
<td>
  <textarea type="text" name="Req" formControlName="req"></textarea>
</td>
</tr>

See that you use formControlName like another formGroup, see the docs

You can see in stackblitz

(*) Before Angular you can write [formGroup]="group" directly, but in recent Angular you need help to angular and say that is a FormGroup