From 987768feb25ce9a8d2adadb48fa7e8f66b0fb8fc Mon Sep 17 00:00:00 2001 From: Joan Pablo Date: Mon, 21 Aug 2023 13:10:13 -0400 Subject: [PATCH] Add markAsPending to controls issue #274 - Allow to mark an abstract control as pending by demand. --- CHANGELOG.md | 7 +++++++ lib/src/models/models.dart | 24 ++++++++++++++++++++++++ test/src/models/form_array_test.dart | 18 ++++++++++++++++++ test/src/models/form_control_test.dart | 15 +++++++++++++++ test/src/models/form_group_test.dart | 18 ++++++++++++++++++ 5 files changed, 82 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 131bbda..9b87a41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 16.1.0 + +## Features + +- Add `markAsPending()` method to `AbstractControl` to allow set the status +to PENDING by demand. + # 16.0.4 ## Fixes diff --git a/lib/src/models/models.dart b/lib/src/models/models.dart index 79e1e65..e2e0532 100644 --- a/lib/src/models/models.dart +++ b/lib/src/models/models.dart @@ -228,6 +228,8 @@ abstract class AbstractControl { /// * VALID: This control has passed all validation checks. /// * INVALID: This control has failed at least one validation check. /// * PENDING: This control is in the midst of conducting a validation check. + /// * DISABLED: This control is exempt from ancestor calculations of + /// validity or value. /// /// These status values are mutually exclusive, so a control cannot be both /// valid AND invalid or invalid AND pending. @@ -420,6 +422,28 @@ abstract class AbstractControl { _updateAncestors(updateParent); } + /// Marks the control as `pending`. + /// + /// A control is pending while the control performs async validation. + /// + /// When [updateParent] is false, mark only this control. When true or not + /// supplied, marks all direct ancestors. Default is true. + /// + /// When [emitEvent] is true or not supplied (the default), a [statusChanged] + /// event is emitted. + /// + void markAsPending({bool updateParent = true, bool emitEvent = true}) { + _status = ControlStatus.pending; + + if (emitEvent) { + this._statusChanges.add(_status); + } + + if (updateParent) { + parent?.markAsPending(updateParent: updateParent, emitEvent: emitEvent); + } + } + /// Disposes the control void dispose() { _statusChanges.close(); diff --git a/test/src/models/form_array_test.dart b/test/src/models/form_array_test.dart index 6ee26a7..fc05df3 100644 --- a/test/src/models/form_array_test.dart +++ b/test/src/models/form_array_test.dart @@ -716,6 +716,24 @@ void main() { // Then: array value is patched expect(array.value, [2, 2], reason: 'array value not patched'); }); + + test('Test that markAsPending() a control, set pending status to the array ' + 'as well.', () { + // Given: an array with valid status. + final array = FormArray([ + FormControl(value: 1), + ]); + + // Expect: the array to be VALID and not PENDING. + expect(array.valid, true); + expect(array.pending, false); + + // When: I call mark a child control as PENDING. + array.controls.first.markAsPending(); + + // Then: the status of the array is PENDING as well. + expect(array.pending, true); + }); }); } diff --git a/test/src/models/form_control_test.dart b/test/src/models/form_control_test.dart index ad66f6e..6ce5186 100644 --- a/test/src/models/form_control_test.dart +++ b/test/src/models/form_control_test.dart @@ -371,5 +371,20 @@ void main() { // Then: a new async validator is added expect(formControl.asyncValidators.length, 1); }); + + test('Test that markAsPending() change the status to PENDING.', () { + // Given: a control with valid status. + final control = FormControl(value: 'Reactive Forms'); + + // Expect: the control to be VALID and not PENDING. + expect(control.valid, true); + expect(control.pending, false); + + // When: I call markAsPending() method. + control.markAsPending(); + + // Then: the status is PENDING. + expect(control.pending, true); + }); }); } diff --git a/test/src/models/form_group_test.dart b/test/src/models/form_group_test.dart index a8e5b66..c1016bc 100644 --- a/test/src/models/form_group_test.dart +++ b/test/src/models/form_group_test.dart @@ -982,5 +982,23 @@ void main() { // Expect: an assertion error expect(form, throwsAssertionError); }); + + test('Test that markAsPending() a control, set pending status to the group ' + 'as well.', () { + // Given: a form group with valid status. + final form = FormGroup({ + 'name': FormControl(value: "Reactive Forms") + }); + + // Expect: the group to be VALID and not PENDING. + expect(form.valid, true); + expect(form.pending, false); + + // When: I call mark a child control as PENDING. + form.control('name').markAsPending(); + + // Then: the status of the Form Group is PENDING as well. + expect(form.pending, true); + }); }); }