I mean I have an order page that has a dynamic order items collection . I want to require the user to have atleast one item in that array. I understand simple usage of a custom validator but in this case I am not validating a single control but an array. How do I say 'If there are no values in the array then give error' ?
createFormGroup(order: Order): FormGroup {
const group = this.fb.group({
id: [order.id],
isItPurchase: [order.isItPurchase],
orderItems: this.fb.array([])
});
order.orderItems.forEach(x => {
var formArray = group.controls.orderItems as FormArray;
formArray.push(this.createOrderItem(x));
});
return group;
}
createOrderItem(item: OrderItem): FormGroup {
const formGroup = this.fb.group({
id: [item.id],
name: [item.name, Validators.required],
unitPrice: [item.unitPrice, Validators.required],
units: [item.units, Validators.required]
});
return formGroup;
}
for a simple case I would do something like
// xxxValidator(control: AbstractControl): { [key: string]: boolean } | null {
// if (control.value === 'xxx') {
// return { 'xxxValidator': true }
// }
// return null;
// };
EDIT 1:
I am closer. I identify when the error exist. But my template is wrong. How do I see the error in the template?
createFormGroup(order: Order): FormGroup {
const group = this.fb.group({
id: [order.id],
isItPurchase: [order.isItPurchase],
orderItems: this.fb.array([])
},
{ validators: [this.testValidation1] }
// { validators: [this.testValidation2] }
);
order.orderItems.forEach(x => {
var formArray = group.controls.orderItems as FormArray;
formArray.push(this.createOrderItem(x));
});
return group;
}
createOrderItem(item: OrderItem): FormGroup {
const formGroup = this.fb.group({
id: [item.id],
name: [item.name, Validators.required],
unitPrice: [item.unitPrice, Validators.required],
units: [item.units, Validators.required]
});
return formGroup;
}
testValidation1(form: FormGroup) {
if (form.value.orderItems.length === 0) {
return { valOrderItems: false };
}
return null;
}
<div>
<div *ngFor="let fg of orderItems.controls; let i=index">
<app-order-item-form [orderItemForm]="fg" (itemDeleted)="onItemDeleted(i)"></app-order-item-form>
</div>
<!-- <span *ngIf="orderForm.errors.valOrderItems"> Must be atleast one orderItem </span> -->
</div>
You can use the required
validator to validate that the form has at least one element
const group = this.fb.group({
id: [order.id],
isItPurchase: [order.isItPurchase],
orderItems: this.fb.array([], [Validators.required])
});
Now to get If the array has no values you can check if the required
validator fails
const error = group.get('orderItems').hasError('required'); // True if form is empty
Create a validator function
function formIsEmpty(control: FormArray) {
if (control.controls.length === 0) {
return { noValue: true}
}
return null;
}
And in your FormGroup
you can use it like
const group = this.fb.group({
id: [order.id],
isItPurchase: [order.isItPurchase],
orderItems: this.fb.array([], [formIsEmpty])
});
And get the error by
group.get('orderItems').hasError('noValue');