I am trying to create a async custom validator to check if a username already exist in a signup form. I have created a service class which calls the Web API (as below) to check the unique user name.
I also created a async custom validator which suppose to call the service and perform the validation. However I am stuck trying to understand how to inject the service into the validator. The service also get injected with Http.
Anyone has any idea how this validation can be done properly?
-Alan-
Custom Validator
export class UserNameValidators {
static shouldBeUnique(control: FormControl) {
....
//Need to call the Signup service here
}
}
Service
@Injectable()
export class SignUpService
{
constructor(private http: Http) {
}
shouldBeUnique(username: string): Observable<boolean> {
let headers = new Headers();
headers.append('Content-Type', 'application/x-www-form-urlencoded');
let options = new RequestOptions({ headers: headers });
return this.http.post('localhost/authentication/api/accounts/user/' + username, '', options)
.map((response: Response) => {
let result = response.toString();
if (result === 'true')
return true
return false;
})
.catch((error: any) => {
if (error.status === 400) {
var cleandata = error._body
.replace(/\\n/g, "\\n")
.replace(/\\'/g, "\\'")
.replace(/\\"/g, '\\"')
.replace(/\\&/g, "\\&")
.replace(/\\r/g, "\\r")
.replace(/\\t/g, "\\t")
.replace(/\\b/g, "\\b")
.replace(/\\f/g, "\\f");
cleandata = cleandata.replace(/[\u0000-\u001F]+/g, "");
return Observable.throw(new Error("Unknown Error"));
}
});
}
}
Update
App.Module
@NgModule({
imports : [BrowserModule, HomeModule, SignupModule,signupRouting, routing],
declarations: [AppComponent],
providers : [AuthService, AuthGuard, SignupService],
bootstrap : [AppComponent]
})
Custom Validator
export class UserNameValidators {
constructor(private service: SignupService) { }
shouldBeUnique(control: FormControl) {
return new Promise((resolve, reject) => {
this.service.shouldBeUnique(control.value).subscribe(
data => {
if (data.length == 0 || data.length == 1) {
resolve(null);
} else {
resolve({ shouldBeUnique: true });
}
},
err => {
resolve({ shouldBeUnique: true });
}
)
});
}
}
Signup.component
export class SignupComponent implements OnInit {
form: FormGroup;
signedUp: boolean = false;
error = '';
constructor(private fb: FormBuilder, private router: Router, private signupService: SignupService) { }
ngOnInit() {
this.form = this.fb.group({
firstname: ['', Validators.required],
lastname: ['', Validators.required],
username: ['', Validators.compose([Validators.required, UserNameValidators.notValidEmail]), new UserNameValidators(this.signupService).shouldBeUnique],
password: ['', Validators.compose([Validators.required, UserNameValidators.cannotContainSpace])],
confirmpassword: ['', Validators.compose([Validators.required, UserNameValidators.cannotContainSpace])]
}, { validator: this.matchingPasswords('password', 'confirmpassword') });
}
}