I am trying to implement a custom validator that checks if the keyed username exists. However, I am running into a problem where the control is always invalid. I have confirmed the webApi is returning the correct values and the validator function is stepping into the proper return statements.
My custom validator is as follows:
import { Directive, forwardRef } from '@angular/core'; import { AbstractControl, ValidatorFn, NG_VALIDATORS, Validator, FormControl } from '@angular/forms'; import { UsersService } from '../_services/index'; import { Users } from '../admin/models/users'; function validateUserNameAvailableFactory(userService: UsersService): ValidatorFn { return (async (c: AbstractControl) => { var user: Users; userService.getUserByName(c.value) .do(u => user = u) .subscribe( data => { console.log("User " + user) if (user) { console.log("Username was found"); return { usernameAvailable: { valid: false } } } else { console.log("Username was not found"); return null; } }, error => { console.log("Username was not found"); return null; }) }) } @Directive({ selector: '[usernameAvailable][ngModel]', providers: [ { provide: NG_VALIDATORS, useExisting: forwardRef(() => UserNameAvailableValidator), multi: true } ] }) export class UserNameAvailableValidator implements Validator { validator: ValidatorFn; constructor(private usersService: UsersService) { } ngOnInit() { this.validator = validateUserNameAvailableFactory(this.usersService); } validate(c: FormControl) { console.log(this.validator(c)); return this.validator(c); } } And the form looks like:
<form #userForm="ngForm" (ngSubmit)="onSubmit()" novalidate> <div class="form form-group col-md-12"> <label for="UserName">User Name</label> <input type="text" class="form-control" id="UserName" required usernameAvailable maxlength="50" name="UserName" [(ngModel)]="user.userName" #UserName="ngModel" /> <div [hidden]="UserName.valid || UserName.pristine" class="alert alert-danger"> <p *ngIf="UserName.errors.required">Username is required</p> <p *ngIf="UserName.errors.usernameAvailable">Username is not available</p> <p *ngIf="UserName.errors.maxlength">Username is too long</p> </div> <!--<div [hidden]="UserName.valid || UserName.pristine" class="alert alert-danger">Username is Required</div>--> </div> </form> I have followed several tutorials proving this structure works, so I am assuming that I am possibly messing up the return from within the validator function.
Also, is there a way I can present the list of errors (I have tried using li with ngFor, but I get nothing from that)?