angularvmware-clarity

VM Ware clarity design form custom validation does not show up or clear the error class


i am trying to get get custom validations for my form using the latest version of clarity and angular but after the successful validation or failure the clr-control-error for this custom error does not show on the Ui , the call does get fired and it validates but also does not remove the .clr-error in a valid scenario but leaves the textbox as red and does not remove the exclamation circle too , it is very similar to

this question

// my component where i am using it 
constructor( private dataService:DataService,private fb: FormBuilder,private sm:FormValidationClass) {
     

      this.step1Form = new FormGroup({
        csiAppId: new FormControl(null, {
          validators: [Validators.required, sm.csiAppIdValidator('csiAppId')],
          updateOn: 'blur'
        }),
        env: new FormControl(null, {
          validators: [Validators.required]
        }),
        appInstanceIdentifier: new FormControl(null, {
          validators: [Validators.required]
        }),
        SNOWappInstanceIdentifier: new FormControl(null, {
          validators: [Validators.required]
        }),
        sltnNumber: new FormControl(null, {
          validators: [Validators.required]
        }),
      });

    }
    
    
    //my validator where i try to call a rest service 
    @Injectable({ providedIn: 'root' })
export class FormValidationClass implements OnInit {

  appIdValuator : string= 'true';

  constructor(public httpClient: HttpClient,private dataService:DataService) {

  }

  ngOnInit(): void {
  }

  csiAppIdValidator(csiAppId: string): ValidatorFn {
    return (control: FormControl) => {
      if(!control){
        return null;
      }

    return this.httpClient.get("/wscrp/cloudvcac/services/rest/validateAppId/"+control.value)
    .subscribe(
        (result : any)=>{
          console.log(">>>"+result.status);
      if( result.status == "Success"){
        alert("valid");
        return  null;
      } else {
        alert("invalid");
        return {invalidAppId : true}
      }
    }
  );
    // return null
    };
  }
}
<form clrForm [formGroup]="step1Form" >
            <div id='one22'>
            <clr-input-container >
                <label class="clr-col-2">CSI AppID</label>
                <input class="clr-col-8" clrInput  formControlName='csiAppId' />
              
                <clr-control-error *clrIfError="'required'">CSI App ID is required!</clr-control-error>
                <clr-control-error *clrIfError="'invalidAppId'">Csi AppID is Invalid!</clr-control-error>
                <!-- <span *clrIfError="'invalidAppId'">dsdsdsdsdsdd</span> -->
            </clr-input-container>
        </div>
        </form>

....my html

where am i going wrong i am just going nuts with this


Solution

  • You made two mistakes here:

    Here's the correct initialization:

    csiAppId: new FormControl(null, {
       validators: [Validators.required],
       asyncValidators: [sm.csiAppIdValidator('csiAppId')], <--- async validators go here
       updateOn: 'blur'
    }),
    

    Here's the correct implementation of your async method:

    csiAppIdValidator(csiAppId: string): AsyncValidatorFn {
      return (control: FormControl): Observable<ValidationErrors | null> => {
        if (!control) {
          return null;
        }
    
        return this.httpClient.get('/wscrp/cloudvcac/services/rest/validateAppId/' + control.value)
          .pipe(map((result: any) => result.status === 'Success' ? null : { invalidAppId: true }));
      };
    }
    

    Please play around with this Stackblitz Example where I mocked http request by providing simple Observable. You can enter something in AppID field and it should fail starting from 4 letters.

    Note: validation happens only on focusout