Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(forms): changes to status not always being emitted to statusChanges observable for async validators. #42553

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/forms/src/model.ts
Expand Up @@ -1167,7 +1167,7 @@ export class FormControl extends AbstractControl {
// `VALID` or `INVALID`.
// The status should be broadcasted via the `statusChanges` observable, so we set `emitEvent`
// to `true` to allow that during the control creation process.
emitEvent: !!asyncValidator
emitEvent: !!this.asyncValidator
});
}

Expand Down Expand Up @@ -1433,7 +1433,7 @@ export class FormGroup extends AbstractControl {
// If `asyncValidator` is present, it will trigger control status change from `PENDING` to
// `VALID` or `INVALID`. The status should be broadcasted via the `statusChanges` observable,
// so we set `emitEvent` to `true` to allow that during the control creation process.
emitEvent: !!asyncValidator
emitEvent: !!this.asyncValidator
});
}

Expand Down Expand Up @@ -1887,7 +1887,7 @@ export class FormArray extends AbstractControl {
// `VALID` or `INVALID`.
// The status should be broadcasted via the `statusChanges` observable, so we set `emitEvent`
// to `true` to allow that during the control creation process.
emitEvent: !!asyncValidator
emitEvent: !!this.asyncValidator
});
}

Expand Down
17 changes: 17 additions & 0 deletions packages/forms/test/form_array_spec.ts
Expand Up @@ -1055,6 +1055,23 @@ describe('FormArray', () => {
expect(g.errors).toEqual({'async': true, 'other': true});
expect(g.pending).toEqual(false);
}));

it('should fire statusChanges events when async validators are added via options object',
fakeAsync(() => {
// The behavior is tested (in other spec files) for each of the model types (`FormControl`,
// `FormGroup` and `FormArray`).
let statuses: string[] = [];

// Create a form control with an async validator added via options object.
const asc = new FormArray([], {asyncValidators: [() => Promise.resolve(null)]});

// Subscribe to status changes.
asc.statusChanges.subscribe((status: any) => statuses.push(status));

// After a tick, the async validator should change status PENDING -> VALID.
tick();
expect(statuses).toEqual(['VALID']);
}));
});

describe('disable() & enable()', () => {
Expand Down
16 changes: 16 additions & 0 deletions packages/forms/test/form_control_spec.ts
Expand Up @@ -879,6 +879,22 @@ describe('FormControl', () => {
tick();
}));

it('should fire statusChanges events for async validators added via options object',
fakeAsync(() => {
// The behavior can be tested for each of the model types.
let statuses: string[] = [];

// Create a form control with an async validator added via options object.
const asc = new FormControl('', {asyncValidators: [() => Promise.resolve(null)]});

// Subscribe to status changes.
asc.statusChanges.subscribe((status: any) => statuses.push(status));

// After a tick, the async validator should change status PENDING -> VALID.
tick();
expect(statuses).toEqual(['VALID']);
}));

it('should fire an event after the status has been updated to pending', fakeAsync(() => {
const c = new FormControl('old', Validators.required, asyncValidator('expected'));

Expand Down
15 changes: 15 additions & 0 deletions packages/forms/test/form_group_spec.ts
Expand Up @@ -819,6 +819,21 @@ describe('FormGroup', () => {
group = new FormGroup({'one': control});
}));

it('should fire statusChanges events for async validators added via options object',
fakeAsync(() => {
// The behavior can be tested for each of the model types.
let statuses: string[] = [];

// Create a form control with an async validator added via options object.
const asc = new FormGroup({}, {asyncValidators: [() => Promise.resolve(null)]});

// Subscribe to status changes.
asc.statusChanges.subscribe((status: any) => statuses.push(status));

// After a tick, the async validator should change status PENDING -> VALID.
tick();
expect(statuses).toEqual(['VALID']);
}));

// TODO(kara): update these tests to use fake Async
it('should fire a statusChange if child has async validation change', done => {
Expand Down