Open eyalhakim opened 5 years ago
I have the same problem. If validateAsync has any delay then the tag (in my case email) is not added on the enter key. However, if the space key (32) or comma key (188) is pressed then two same tags (emails) are added. Here is the code that I have:
@Component({
selector: 'email-input',
template: `
<h5>Email</h5>
{{emails | json}}
<br/>
<tag-input [ngModel]="emails"
(onAdd)="onItemAdded($event)"
[theme]="'ark-tag-theme'"
[clearOnBlur]="true"
[blinkIfDupe]="true"
[addOnBlur]="true"
[disable]="!hasPermission"
[inputClass]="'input-of-tag-area-class'"
[placeholder]="'Enter email'"
[secondaryPlaceholder]="'Enter email'"
(onRemove)="onRemoveEmail($event)"
[errorMessages]="errorMessages"
[validators]="validators"
[asyncValidators]="asyncValidators"
[separatorKeyCodes]="[32,188]"
[separatorKeys]="[' ', ',']">
</tag-input>
`
})
export class EmailInputComponent implements OnInit {
@Input() emails: DisplayItem[];
@Input() hasPermission: boolean;
private readonly emailExist = 'Email address already exist';
private readonly emailInvalid = 'It is not valid email address';
errorMessages: {'emailAlreadyExist@': string, 'invalidEmail@': string};
validators: ValidatorFn[];
asyncValidators: AsyncValidatorFn[];
ngOnInit(): void {
this.setEmailValidation();
}
setEmailValidation = (): void => {
this.asyncValidators = [this.validateAsync.bind(this)];
this.validators = [this.emailValidation.bind(this)];
this.errorMessages = {
'emailAlreadyExist@': this.emailExist,
'invalidEmail@': this.emailInvalid
};
}
onItemAdded(newEmail: TagModel): void {
const email = newEmail as DisplayItem;
this.emails.push(email);
}
onRemoveEmail(removedEmail: TagModel): void {
const email = removedEmail as DisplayItem;
this.emails = this.emails.filter(e => e.display !== email.display);
}
private validateAsync = (control: FormControl): Observable<any> => {
if (this.validateEmail(control.value) && !this.emailExistInAddEmailArea(control.value)) {
// in real app line below is doing to the rest API to check if entered email exist in the System.
// If yes it return Observable object { emailAlreadyExist@: true} if not it returns Observable(null)
return of(null).pipe(delay(1000));
}
return of(null);
}
private emailExistInAddEmailArea = (email: string): boolean => {
return !(!this.emails.find( e => e.display === email));
}
private validateEmail = (email: string): boolean => {
const regEx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
return regEx.test(email);
}
private emailValidation = (control: FormControl) => {
if (!control.value) {
return null;
}
if (!this.validateEmail(control.value)) {
return {'invalidEmail@': true};
}
if (this.emailExistInAddEmailArea(control.value)) {
return {'emailAlreadyExist@': true};
}
return null;
}
}
Node if the function validateAsync = (control: FormControl): Observable
Angular version: ~7.2.0 ngx-chips: 2.0.0-beta.0
Browser: tested on Chrome and Firefox
PLEASE MAKE SURE THAT:
I'm submitting a ... (check one with "x")
Current behavior
While an async validator exists, tags can't be added
Expected behavior
Tags should be added if validation passes
Minimal reproduction of the problem with instructions (if applicable)
This happens in your own demo
What do you use to build your app?. Please specify the version
angular-cli
Angular version:
7.2.2
ngx-chips version:
2.0.0-beta.0
Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]
Chrome