Is there any chance that i can achieve this with a subject? for the time being i have only acheived this with a Promise. so i call the resolve method and that works correct.
i was trying to do the following.
forbiddenEmail(control: FormControl): Observable<any> {
const obs = new Subject();
setTimeout(() => {
if (control.value === '[email protected]') {
obs.next({'emailIsForbidden': true});
} else {
obs.next(null);
}
}, 2000);
return obs;
}
Here, im trying to emit the event whenever the value is [email protected], otherwise null as the docs in Angular say about the validators.
im trying to simulate lets say a backend service thats why i implement setTimeout fucntion and give a timeout of 2 secs.
Now the problem is that when i inspect the input element which i place the validator (an email input element) then class ng-pending
is displayed always.
so, for some reason im not subscribing to it i know that. but how i could?
this is where i call the validator inside the FormGroup.
ngOnInit() {
this.signupForm = new FormGroup({
'userData': new FormGroup({
'username': new FormControl(null, [Validators.required, this.forbiddenNames.bind(this)]),
'email': new FormControl(null, [Validators.required, Validators.email], this.forbiddenEmail.bind(this))
}),
'gender': new FormControl('male'),
'hobbies': new FormArray([])
});
}
You need to complete your observable:
setTimeout(() => {
if (control.value === '[email protected]') {
obs.next({'emailIsForbidden': true});
} else {
obs.next(null);
}
obs.complete();
}, 2000);
But this could be defined in a much simpler way:
forbiddenEmail2(control: FormControl): Observable<any> {
const result = control.value === '[email protected]' ? {'emailIsForbidden': true} : null;
return Observable.of(result).delay(2000);
}
This is also more correct, since it actually validates the input as it is at the moment the validator is invoked, instead of validating the input as it is 2 seconds later. In a more realistic use-case: you would get the input immediately, and send it to the backend.