SBB SBB - 3 years ago 235
TypeScript Question

Angular2 Reactive Forms Validation

I have a simple component that implements reactive forms and sets up 7 input fields which are

select
inputs.

I am trying to apply a validator on it to force at least one of them to contain a value.

Component:

renderForm() {
this.importForm = this.fb.group({
costCenter: [],
area: [],
silo: [],
department: [],
location: [],
segment: [],
role: []
},
{
validator: (formGroup: FormGroup) => {
return this.validateFilter(formGroup);
}
});
}

/**
* Checks to see that at least one of the filter
* options have been filled out prior to searching
* for employees.
*
* @param formGroup
*/
validateFilter(formgroup: FormGroup) {
if (formgroup.controls["costCenter"].value ||
formgroup.controls["area"].value ||
formgroup.controls["silo"].value ||
formgroup.controls["department"].value ||
formgroup.controls["location"].value ||
formgroup.controls["segment"].value ||
formgroup.controls["role"].value
) {
return { validateFilter: true };
} else {
return null;
}
}


When I submit my form an inspect the
form
itself, it keeps saying that its valid, even though none of the inputs have been filled out.

When I look at the individual form control values, they are displaying as
null
, verifying that not value has been stored.

Anything noticeable that I am doing wrong?

Update:

Not sure if this matters but a value of my input is an array:

enter image description here

I would think that this is still considered to be
true
when testing to see if it has a value?

Update 2:
Here is a snippet of my HTML. This snippet is the same for each dropdown, just references a different function to populate it.

<tr>
<td class="col-md-2 strong">Area</td>
<td>
<div class="form-group">
<ng-select formControlName="area" [allowClear]="true" [multiple]="true" [items]="getAreas()" placeholder="Select one or more Areas">
</ng-select>
</div>
</td>
</tr>


Update 3:

As requested, here is the full HTML template.

<tbody>
<tr>
<td class="col-md-2 strong">Cost Center</td>
<td>
<div class="form-group">
<ng-select formControlName="costCenter" [allowClear]="true" [multiple]="true" [items]="getCostCenters()" placeholder="Select one or more Cost Centers">
</ng-select>
</div>
</td>
</tr>
<tr>
<td class="col-md-2 strong">Area</td>
<td>
<div class="form-group">
<ng-select formControlName="area" name="area" [allowClear]="true" [multiple]="true" [items]="getAreas()" placeholder="Select one or more Areas">
</ng-select>
</div>
</td>
</tr>
<tr>
<td class="col-md-2 strong">Silo</td>
<td>
<div class="form-group">
<ng-select formControlName="silo" name="silo" [allowClear]="true" [multiple]="true" [items]="getSilos()" placeholder="Select one or more Silos">
</ng-select>
</div>
</td>
</tr>
<tr>
<td class="col-md-2 strong">Department</td>
<td>
<div class="form-group">
<ng-select formControlName="department" name="department" [allowClear]="true" [multiple]="true" [items]="getDepartments()" placeholder="Select one or more Departments">
</ng-select>
</div>
</td>
</tr>
<tr>
<td class="col-md-2 strong">Location</td>
<td>
<div class="form-group">
<ng-select formControlName="location" name="location" [allowClear]="true" [multiple]="true" [items]="getLocations()" placeholder="Select one or more Locations">
</ng-select>
</div>
</td>
</tr>
<tr>
<td class="col-md-2 strong">Segment</td>
<td>
<div class="form-group">
<ng-select formControlName="segment" name="segment" [allowClear]="true" [multiple]="true" [items]="getSegments()" placeholder="Select one or more Segments">
</ng-select>
</div>
</td>
</tr>
<tr>
<td class="col-md-2 strong">Role</td>
<td>
<div class="form-group">
<ng-select formControlName="role" name="role" [allowClear]="true" [multiple]="true" [items]="getRoles()" placeholder="Select one or more Roles">
</ng-select>
</div>
</td>
</tr>
</tbody>


Update 4:

As a test, I commented out all of the validation logic and just returned
return { validFilter: true };
expecting it to tell my form that its
valid
. However, this was not the case and the form is still
invalid
.

Seems like there may be an underlying issue somewhere else?

Answer Source

So I could be wrong, but at first glance it looks like you have the validator mixed up. It should be the following:

/**
 * Checks to see that at least one of the filter
 * options have been filled out prior to searching
 * for employees.
 *
 * @param formGroup
 */
validateFilter(formgroup: FormGroup) {
    if (formgroup.controls["costCenter"].value ||
        formgroup.controls["area"].value ||
        formgroup.controls["silo"].value ||
        formgroup.controls["department"].value ||
        formgroup.controls["location"].value ||
        formgroup.controls["segment"].value ||
        formgroup.controls["role"].value
    ) {
        return null
    } else {
        return { noFilterOptionsSet: true };
    }
}

The way validators work is that a "valid" validator returns null, in other words: "I didn't find anything wrong". If it finds something it returns an object with a descriptively named property with a boolean value that further describes the state of the property, most likely "true". This is used to trigger different errors and inform the form of which error occured so you can apply different labels and error messages.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download