4

I've written a web api function that takes a username from the textfield and checks if the username is already taken. To know if the username is available or not, my server returns Y if it is available and N if its not.

To validate the username, I'm using a ValidatorFn in Angular2 so validate the input. However, my validator function is not working.

Here is the validator function:

interface Validator<T extends FormControl> { (c: T): { [error: string]: any }; } function validateUsername(c: string) : ValidatorFn { return (this.isAvailable(c)=='Y') ? null : { validateUsername: { valid: false } }; } 

Here is the isAvailable function:

private isAvailable(username: string) { let usernameAvailable; let url = 'URL/api/auth/checkuser/' + username; let headers = new Headers(); headers.append('User', sessionStorage.getItem('username')); headers.append('Token', sessionStorage.getItem('token')); headers.append('AccessTime', sessionStorage.getItem('AccessTime')); let options = new RequestOptions({ headers: headers }); this.http.get(url, options) .subscribe((res: Response) => usernameAvailable); return usernameAvailable; //returns Y or N } 

Form Builder:

complexForm: FormGroup; constructor(private http: Http, fb: FormBuilder) { this.complexForm = fb.group({ 'username': [null, Validators.compose([Validators.required, Validators.minLength(5), Validators.maxLength(10), validateUsername(this.complexForm.controls['username'].value)])], }) } 

validateUsername(this.complexForm.controls['username'].value) is failing and I'm getting this error:

[ts] Type '{ validateUsername: { valid: boolean; }; }' is not assignable to type 'ValidatorFn'. Object literal may only specify known properties, and 'validateUsername' does not exist in type 'ValidatorFn'. (property) validateUsername: { valid: boolean; } 
2
  • but isn't validateUsername a ValidatorFn? I figured ValidatorFns return null if they are passed and false if failed Commented Aug 18, 2017 at 8:50
  • @Vega I just attempted, it still doesn't accept a boolean Commented Aug 18, 2017 at 8:52

1 Answer 1

5

You not adding your validator function correctly. You don't need to call your function when you register it:

this.complexForm = fb.group({ 'username': [null, Validators.compose( [ Validators.required, Validators.minLength(5), Validators.maxLength(10), validateUsername <----- don't call it here ] )], }) 

You can see that some functions are called:

Validators.minLength(5), 

But that is factory function call and not a validator function call. During initialization they return ValidatorFn:

 /** * Validator that requires controls to have a value of a minimum length. */ static minLength(minLength: number): ValidatorFn { return (control: AbstractControl): ValidationErrors | null => { ... } 

See more in the official docs.

Also, it seems that your validator is async, so you have to pass it in the async array. And I don't think you need Validators.compose. The correct configuration should therefore be like this:

this.complexForm = fb.group({ 'username': [null, [ Validators.required, Validators.minLength(5), Validators.maxLength(10), ], [validateUsername]] }) 

Regarding the error:

Type '{ valid: boolean; }' is not assignable to type ValidatorFn.

You need to use the correct return type ValidationErrors instead of ValidatorFn:

function validateUsername(c: string) : ValidationErrors { return (this.isAvailable(c)=='Y') ? null : { validateUsername: { valid: false } }; } 
Sign up to request clarification or add additional context in comments.

6 Comments

thanks for clarfiying the validator function call. however I'm still having an issue with the function itself. This error to be precise: [ts] Type '{ valid: boolean; }' is not assignable to type 'ValidatorFn'. Object literal may only specify known properties, and 'valid' does not exist in type 'ValidatorFn'. it says valid is not a type of validatorFn however its used normally in the docs..
you specified the wrong return type, use ValidationErrors instead of ValidatorFn. I updated my answer
Would the string set to false return an invalid flag for the custom validator?
what string? check my udpated answer, the type was incorrect. You need to use the correct return type ValidationErrors instead of ValidatorFn
Yeah I noticed, thanks again for the help. The validator is working now however I'm now facing a different issue that I'm not able to get the username to be passed into the validator from the textfield. You solved my initial issue. thanks :)
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.