Looking to implement an async custom validator for checking the availability of a username in a signup form? I've set up a service class that interacts with the Web API (as shown below) to perform this check.
In addition, I've developed an async custom validator that is supposed to interface with the service and carry out the validation process. However, I'm encountering difficulties understanding how to inject the service into the validator. The service itself is injected with Http.
If anyone has insights on how to execute this validation correctly, your input would be much appreciated.
-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') });
}
}