Validation Error Message not getting displayed for custom validation in Angular 2 -
i have register form user need provide username. when customer enters username, want show validation error message if username exists in db or not.
register.html
<-- code here--> <div class="form-group"> <label for="username" class="col-sm-3 control-label">username</label> <div class=" col-sm-6"> <input type="text" ngcontrol="username" maxlength="45" class="form-control" [(ngmodel)]="parent.username" placeholder="username" #username="ngform" required data-is-unique/> <validation-message control="username"></validation-message> </div> </div> <--code here-->
register.component.ts
import {component} 'angular2/core'; import {ngform, formbuilder, validators, form_directives} 'angular2/common'; import {validationservice} '../services/validation.service'; import {validationmessages} './validation-messages.component'; @component({ selector: 'register', templateurl: './views/register.html', directives: [router_directives, validationmessages, form_directives], providers: [] }) export class parentsignupcomponent { parentsignupform: any; constructor(private _formbuilder: formbuilder) { this._stateservice.isauthenticatedevent.subscribe(value => { this.onauthenticationevent(value); }); this.parent = new parentsignupmodel(); this.parentsignupform = this._formbuilder.group({ 'firstname': ['', validators.compose([validators.required, validators.maxlength(45), validationservice.namevalidator])], 'middlename': ['', validators.compose([validators.maxlength(45), validationservice.namevalidator])], 'lastname': ['', validators.compose([validators.required, validators.maxlength(45), validationservice.namevalidator])], 'username': ['', validators.compose([validators.required, validationservice.checkusername])] }); } }
validation-message.component
import {component, host} 'angular2/core'; import {ngformmodel} 'angular2/common'; import {validationservice} '../services/validation.service'; @component({ selector: 'validation-message', inputs: ['validationname: control'], template: `<div *ngif="errormessage !== null" class="error-message"> {{errormessage}}</div>` }) export class validationmessages { private validationname: string; constructor (@host() private _formdir: ngformmodel) {} errormessage() { let control = this._formdir.form.find(this.validationname); (let propertyname in control.errors) { if (control.errors.hasownproperty(propertyname) && control.touched) { return validationservice.getvalidatorerrormessage(propertyname); } } return null; } }
validation-service.ts
import {injectable, injector} 'angular2/core'; import {control} 'angular2/common'; import {observable} 'rxjs/observable'; import {http, response, http_providers} 'angular2/http'; import 'rxjs/rx'; interface validationresult { [key:string]:boolean; } @injectable() export class validationservice { static getvalidatorerrormessage(code: string) { let config = { 'required': 'this field required!', 'maxlength': 'field long!', 'invalidname': 'this field can contain alphabets, space, dot, hyphen, , apostrophe.', 'useralreadyinuse': 'username selected in use! please try another.' }; return config[code]; } static checkusername(control: control): promise<validationresult> { let injector = injector.resolveandcreate([http_providers]); let http = injector.get(http); let alreadyexists: boolean; if (control.value) { return new promise((resolve, reject) => { settimeout(() => { http.get('/isusernameunique/' + control.value).map(response => response.json()).subscribe(result => { if (result === false) { resolve({'useralreadyinuse': true}); } else { resolve(null); } }); }, 1000); }); } } }
now, when run, , give username exists in db, value of 'result' variable getting false, expected , correct. validation error message not getting displayed. able run , validation error message other custom validation functions. using angular 2.0.0-beta.15. can me understand issue?
there known issues async validation
- https://github.com/angular/angular/issues/1068
- https://github.com/angular/angular/issues/7538
- https://github.com/angular/angular/issues/8118
- https://github.com/angular/angular/issues/8923
- https://github.com/angular/angular/issues/8022
this code can simplified
return new promise((resolve, reject) => { settimeout(() => { http.get('/isusernameunique/' + control.value).map(response => response.json()) .subscribe(result => { if (result === false) { resolve({'useralreadyinuse': true}); } else { resolve(null); } }); }, 1000); });
to
return http.get('/isusernameunique/' + control.value).map(response => response.json()) .timeout(200, new error('timeout has occurred.')); .map(result => { if (result === false) { resolve({'useralreadyinuse': true}); } else { resolve(null); } }).topromise();
don't forget import map
, timeout
, , topromise
.
if use subscribe()
instead of then()
on caller site, can event omit topromise()