Angular Reactive Form: validate unique "check" by type in FormArray of FormGroups using RxWeb Validator

24 Views Asked by At

I am having difficulty validating a reactive form in Angular. The form consists of a formArray which contains formGroups with formControls for the contact properties:

export enum EnumContactType
{
    Phone = 1,
    Email = 2
}

const form = this.#FormBuilder.group(
        {
            Username: [''],
            Contacts: this.#FormBuilder.array(
            [
                this.#FormBuilder.group(
                {
                    Id: [null],
                    ContactTypeId: [EnumContactType.Phone, [RxwebValidators.required()]],
                    Value: ['', [RxwebValidators.required(), RxwebValidators.unique()]],
                    Description: ['', [RxwebValidators.required()]],
                    IsMain: [true, [RxwebValidators.unique({ messageKey: 'uniqueMainContactType' })]]
                }),
                this.#FormBuilder.group(
                {
                    Id: [null],
                    ContactTypeId: [EnumContactType.Email, [RxwebValidators.required()]],
                    Value: ['', [RxwebValidators.required(), RxwebValidators.unique(), RxwebValidators.email()]],
                    Description: ['', [RxwebValidators.required()]],
                    IsMain: [true, [RxwebValidators.unique({ messageKey: 'uniqueMainContactType' })]]
                })
            ])
        });

CreateContactForm(contact: IContact | null = null)
    {
        const group = this.#FormBuilder.group(
        {
            Id: [contact?.Id || null],
            ContactTypeId: [contact?.ContactTypeId || null, [RxwebValidators.required()]],
            Value: [contact?.Value || '', [RxwebValidators.required(), RxwebValidators.unique()]],
            Description: [contact?.Description || '', [RxwebValidators.required()]],
            IsMain: [contact?.IsMain || false, [RxwebValidators.unique({ messageKey: 'uniqueMainContactType'
            })]]
        });

        if (contact?.ContactTypeId == EnumContactType.Email)
        {
            group.controls.Value.setValidators([RxwebValidators.required(), RxwebValidators.unique(), RxwebValidators.email()]);
        }

        return group;
    }

The form is used to add a list of contacts which can be of two types: email or phone. For each added contact, only one contact can be marked as "Main": there can only be one main email contact and one main phone contact. If no contacts of one of the possible types is added, it is not mandatory to have main contacts. The user can add more contacts of the same type, but only one can be "IsMain".

For validations, I am using the RxwebValidators library (https://docs.rxweb.io/form-validations/unique/validators). Looking at the documentation, I thought I could use the "unique" validator or the "oneOf" validator, but given the conditional requirement of the contact type, I am not seeing how it will be possible. I wanted to keep the validation with RxwebValidators to maintain consistent error access through the messageKey property.

0

There are 0 best solutions below