angulartypescriptangular-custom-validators

Custom Validator on Angular logic gets implemented successfully but does not show the error message on my web page UI /HTML


so I was doing a custom validator on my Angular form which works in the following way:

excerpt from my component.ts file:

creteRoute(): FormGroup {
    return this.fb.group({
      'departure_airport_id': ['', Validators.required],
      'departure_airport_code': ['', Validators.required],
      'route_freequency': ['', [Validators.required, Validators.pattern("^[0-9]*$")]],
      'arrival_airport_id': ['', Validators.required],
      'arrival_airport_code': ['', Validators.required],
      'target_price': ['', Validators.required],
      'start_date': ['', Validators.required]
    }
    ,{
      validator: MustBeUnique('departure_airport_code','arrival_airport_code')
    }
);
  }

The MustBeUnique is imported from a separate file with the code:

export function MustBeUnique(controlName:string,uniqueControlName:string){
return (formGroup:FormGroup)=>{
    const control=formGroup.controls[controlName];
    const uniqueControl=formGroup.controls[uniqueControlName];
    
    if (uniqueControl.errors && !uniqueControl.errors.mustBeUnique) {
        console.log("Default error case")
        return;
      }
    if(control.value === uniqueControl.value){
        console.log("Arrival and Departure cannot be same location")
        uniqueControl.setErrors({mustBeUnique:true})

    }
    else{
        console.log("Values are unique")
        uniqueControl.setErrors(null)
    }
}
}

The html code excerpt if as follows:

 <div class="card card-body border-bottom" formArrayName="routes"
      *ngFor="let item of newRequestForm.get('routes')['controls']; let i = index;">
      <div [formGroupName]="i">
<input formControlName="arrival_airport_code" name="arrival_airport_id{{i}}"
                [attr.list]="'arrivalAirport'+i" type="text" placeholder="Search Airport"
                id="arrivalAirportText{{i}}" class="form-control" (keypress)="changeSearchFlag(true)"
                (keyup)="onSearchAirport($event.target.value, i, 'arrive')" autocomplete="off">
              <datalist class="form-control" id="arrivalAirport{{i}}" hidden>
                <option *ngFor="let x of arrivalAirports" value="{{x?.code}}">{{x?.name}}</option>
              </datalist>
              <input type="hidden" formControlName="arrival_airport_id">
              <div>
              <small class="text-danger"
                *ngIf="formSubmitted && item.controls.arrival_airport_id.hasError('required')">
                This field is required.
              </small>
              
              <small class="text-danger"
                *ngIf="formSubmitted && item.controls.arrival_airport_code.mustBeUnique">
                
                Departure and Arrival cannot be at the same place
              </small>

The issue I'm facing here is that the logic from MustBeUnique file gets executed successfully as I traced them out using console.log() but the error message that I set using the setErrors isn't showing up on my HTML.

The logic simply says that arrival and departure destination selected by a user for airports shouldn't be the same. All other validators (built-in) work perfectly


Solution

  • item.controls.arrival_airport_code.mustBeUnique You are accessing the error in the control itself.

    Instead, your error will be available on errors property of FormControl.

    Change to: item.controls.arrival_airport_code.errors.mustBeUnique