Skip to content

Instantly share code, notes, and snippets.

@hbweb
Last active August 2, 2018 08:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hbweb/5c13502f57d465b220141a8e1e9e218d to your computer and use it in GitHub Desktop.
Save hbweb/5c13502f57d465b220141a8e1e9e218d to your computer and use it in GitHub Desktop.
Angular Async Validator - Medium Post
import { Directive } from '@angular/core';
import { AsyncValidatorFn, AsyncValidator, NG_ASYNC_VALIDATORS, AbstractControl, ValidationErrors } from '@angular/forms';
import { Observable } from "rxjs/Observable";
import 'rxjs/add/operator/map';
import { ProductService } from '../product-service';
import { map, tap } from 'rxjs/operators';
export function existingProductCodeValidator(productService: ProductService): AsyncValidatorFn {
return (control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> => {
return productService.getProductByCode(control.value).pipe(
map(product => product ? {"productExists": true} : null),
tap(res => control.setErrors(res))
).first();
};
}
@Directive({
selector: '[productExists][formControlName],[productExists][formControl],[productExists][ngModel]',
providers: [{provide: NG_ASYNC_VALIDATORS, useExisting: ExistingProductValidatorDirective, multi: true}]
})
export class ExistingProductValidatorDirective implements AsyncValidator {
constructor(private userService: UserService) { }
validate(control: AbstractControl): Promise<ValidationErrors | null> | Observable<ValidationErrors | null> {
return existingProductCodeValidator(this.productService)(control);
}
}
<div class="form-group">
<label for="productCode">Enter Product Code: </label>
<input formControlName="productCode" id="productCode" />
<div *ngIf="form.get('productCode').hasError('productExists')">
Product code found! Please continue.
</div>
</div>
import { existingProductCodeValidator } from 'email-validator.directive'; // Import product code validator function
@Component({
selector: 'product-search',
templateUrl: './product-search.component.html'
})
export class ProductSearchFormComponent implements OnInit {
userForm: FormGroup;
constructor(private formBuilder:FormBuilder, private productService: ProductService) {
}
ngOnInit() {
this.userForm = this.formBuilder.group({
productCode: ['',
[ Validators.required ], //sync validators
[ existingProductCodeValidator(this.productService) ] //async validators
],
otherFields: ['',
[ Validators.required], //sync validators
]
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment