Permalink
Browse files

feat(forms): add hasError and getError to AbstractControlDirective (#…

…11985)

Allows cleaner expressions in template-driven forms.

Before:

    <label>Username</label><input name="username" ngModel required #username="ngModel">
    <div *ngIf="username.dirty && username.control.hasError('required')">Username is required</div>

After:

    <label>Username</label><input name="username" ngModel required #username="ngModel">
    <div *ngIf="username.dirty && username.hasError('required')">Username is required</div>

Fixes #7255
  • Loading branch information...
cexbrayat authored and alxhub committed Oct 19, 2016
1 parent 24facde commit 592f40aa9c89265e59924d42f5a173d0803b8d3e
@@ -57,4 +57,12 @@ export abstract class AbstractControlDirective {
reset(value: any = undefined): void {
if (isPresent(this.control)) this.control.reset(value);
}
+
+ hasError(errorCode: string, path: string[] = null): boolean {
+ return isPresent(this.control) ? this.control.hasError(errorCode, path) : false;
+ }
+
+ getError(errorCode: string, path: string[] = null): any {
+ return isPresent(this.control) ? this.control.getError(errorCode, path) : null;
+ }
}
@@ -158,6 +158,15 @@ export function main() {
expect(form.valueChanges).toBe(formModel.valueChanges);
});
+ it('should reexport control methods', () => {
+ expect(form.hasError('required')).toBe(formModel.hasError('required'));
+ expect(form.getError('required')).toBe(formModel.getError('required'));
+
+ formModel.setErrors({required: true});
+ expect(form.hasError('required')).toBe(formModel.hasError('required'));
+ expect(form.getError('required')).toBe(formModel.getError('required'));
+ });
+
describe('addControl', () => {
it('should throw when no control found', () => {
const dir = new FormControlName(form, null, null, [defaultAccessor]);
@@ -329,6 +338,15 @@ export function main() {
expect(form.enabled).toBe(formModel.enabled);
});
+ it('should reexport control methods', () => {
+ expect(form.hasError('required')).toBe(formModel.hasError('required'));
+ expect(form.getError('required')).toBe(formModel.getError('required'));
+
+ formModel.setErrors({required: true});
+ expect(form.hasError('required')).toBe(formModel.hasError('required'));
+ expect(form.getError('required')).toBe(formModel.getError('required'));
+ });
+
describe('addControl & addFormGroup', () => {
it('should create a control with the given name', fakeAsync(() => {
form.addFormGroup(personControlGroupDir);
@@ -406,6 +424,15 @@ export function main() {
expect(controlGroupDir.disabled).toBe(formModel.disabled);
expect(controlGroupDir.enabled).toBe(formModel.enabled);
});
+
+ it('should reexport control methods', () => {
+ expect(controlGroupDir.hasError('required')).toBe(formModel.hasError('required'));
+ expect(controlGroupDir.getError('required')).toBe(formModel.getError('required'));
+
+ formModel.setErrors({required: true});
+ expect(controlGroupDir.hasError('required')).toBe(formModel.hasError('required'));
+ expect(controlGroupDir.getError('required')).toBe(formModel.getError('required'));
+ });
});
describe('FormArrayName', () => {
@@ -434,6 +461,15 @@ export function main() {
expect(formArrayDir.disabled).toBe(formModel.disabled);
expect(formArrayDir.enabled).toBe(formModel.enabled);
});
+
+ it('should reexport control methods', () => {
+ expect(formArrayDir.hasError('required')).toBe(formModel.hasError('required'));
+ expect(formArrayDir.getError('required')).toBe(formModel.getError('required'));
+
+ formModel.setErrors({required: true});
+ expect(formArrayDir.hasError('required')).toBe(formModel.hasError('required'));
+ expect(formArrayDir.getError('required')).toBe(formModel.getError('required'));
+ });
});
describe('FormControlDirective', () => {
@@ -466,6 +502,15 @@ export function main() {
it('should reexport control properties', () => { checkProperties(control); });
+ it('should reexport control methods', () => {
+ expect(controlDir.hasError('required')).toBe(control.hasError('required'));
+ expect(controlDir.getError('required')).toBe(control.getError('required'));
+
+ control.setErrors({required: true});
+ expect(controlDir.hasError('required')).toBe(control.hasError('required'));
+ expect(controlDir.getError('required')).toBe(control.getError('required'));
+ });
+
it('should reexport new control properties', () => {
var newControl = new FormControl(null);
controlDir.form = newControl;
@@ -486,15 +531,16 @@ export function main() {
describe('NgModel', () => {
let ngModel: NgModel;
+ let control: FormControl;
beforeEach(() => {
ngModel = new NgModel(
null, [Validators.required], [asyncValidator('expected')], [defaultAccessor]);
ngModel.valueAccessor = new DummyControlValueAccessor();
+ control = ngModel.control;
});
it('should reexport control properties', () => {
- var control = ngModel.control;
expect(ngModel.control).toBe(control);
expect(ngModel.value).toBe(control.value);
expect(ngModel.valid).toBe(control.valid);
@@ -511,6 +557,15 @@ export function main() {
expect(ngModel.enabled).toBe(control.enabled);
});
+ it('should reexport control methods', () => {
+ expect(ngModel.hasError('required')).toBe(control.hasError('required'));
+ expect(ngModel.getError('required')).toBe(control.getError('required'));
+
+ control.setErrors({required: true});
+ expect(ngModel.hasError('required')).toBe(control.hasError('required'));
+ expect(ngModel.getError('required')).toBe(control.getError('required'));
+ });
+
it('should throw when no value accessor with named control', () => {
const namedDir = new NgModel(null, null, null, null);
namedDir.name = 'one';
@@ -610,6 +665,15 @@ export function main() {
expect(controlNameDir.disabled).toBe(formModel.disabled);
expect(controlNameDir.enabled).toBe(formModel.enabled);
});
+
+ it('should reexport control methods', () => {
+ expect(controlNameDir.hasError('required')).toBe(formModel.hasError('required'));
+ expect(controlNameDir.getError('required')).toBe(formModel.getError('required'));
+
+ formModel.setErrors({required: true});
+ expect(controlNameDir.hasError('required')).toBe(formModel.hasError('required'));
+ expect(controlNameDir.getError('required')).toBe(formModel.getError('required'));
+ });
});
});
}
@@ -84,6 +84,8 @@ export declare abstract class AbstractControlDirective {
valid: boolean;
value: any;
valueChanges: Observable<any>;
+ getError(errorCode: string, path?: string[]): any;
+ hasError(errorCode: string, path?: string[]): boolean;
reset(value?: any): void;
}

0 comments on commit 592f40a

Please sign in to comment.