I need help with formArray
validation in reactive form. I want validate each item in array, but i have no idea how can i do that. Thanks.
html code:
<label for="name">name:</label>
<input formControlName="name" id="name" type="text">
<div *ngIf="name.invalid && (name.dirty || name.touched)">
<div *ngIf="name.errors.required">
required
</div>
</div>
TypeScript code:
createForm() {
this.form = this.fb.group({
person: this.fb.array([this.initItemRows()])
});
}
initItemRows() {
return this.fb.group({
name: [''],
info: ['']
});
}
addNewRow() {
const control = <FormArray>this.form.controls['person'];
control.push(this.initItemRows());
}
deleteRow(index: number) {
const control = <FormArray>this.form.controls['person'];
control.removeAt(index);
}
get name() { return this.form.get('person.name'); }
get info() { return this.form.get('person.info'); }
I tried this:
initItemRows() {
return this.fb.group({
name: ['', Validators.required ],
info: ['', Validators.required ]
});
}
It doesnt work..
A FormArray aggregates the values of each child FormControl into an array. It calculates its status by reducing the status values of its children. For example, if one of the controls in a FormArray is invalid, the entire array becomes invalid.
It provides some of the shared behavior that all controls and groups of controls have, like running validators, calculating status, and resetting state. It also defines the properties that are shared between all sub-classes, like value , valid , and dirty . It shouldn't be instantiated directly.
Your getters for name
and info
actually don't target the specific form controls, since your person
is a formArray, for example this.form.get('person.name');
does not exist in your form. What you need to do, is use the iteration for each formgroup and target that group with its controls, so your template should look like this:
<div *ngFor="let p of form.controls.person.controls; let i = index"
[formGroupName]="i">
<label for="name">name:</label>
<input formControlName="name" id="name" type="text">
<!-- check if the name in this group has the error -->
<div *ngIf="p.controls.name.dirty">
<div *ngIf="p.hasError('required', 'name')">Required</div>
</div>
</div>
DEMO
Furthermore a suggestion is, that you can shorten your code a bit and remove a method that isn't really needed for initializing/adding formgroup to your array, so here I removed the addNewRow
, initItemRows
can be called when you want a new row added.
this.form = this.fb.group({
person: this.fb.array([])
});
this.initItemRows();
initItemRows() {
let ctrl = <FormArray>this.form.controls.person;
ctrl.push(this.fb.group({
name: ['', Validators.required],
info: ['', Validators.required]
}))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With