Repository navigation
Conversation
AndrewKushnir
left a comment
There was a problem hiding this comment.
Thanks for creating this PR @benbraou 👍
It looks like the change is in the right direction and I've added a couple comments.
|
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
|
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
|
Hi @benbraou, thanks for the reply and applying additional changes 👍 I had another look and I'm wondering if we can reuse existing Also there are some failing tests on CI, could you please look into them? It looks like most of them are added as a part of this PR. FYI, I also started tests in Google's codebase (blueprint and global, links are internal-only) to see how this change might affect existing apps. Thank you. |
|
Hi @AndrewKushnir. Thank you for the review. Sorry about the failing tests, I should've let you know that I haven't finished updating them yet. They should be fine now. this._asyncValidationSubscription = obs.subscribe((errors: ValidationErrors|null) => {
this._asyncValidationSubscription = undefined;
this.setErrors(errors, {emitEvent});
});I just have one comment, the order is important. The subscription needs to be set to undefined before setting the errors. This is because setErrors(errors: ValidationErrors|null, opts: {emitEvent?: boolean} = {}): void {
(this as {errors: ValidationErrors | null}).errors = errors;
this._updateControlsErrors(opts.emitEvent !== false);
}
_updateControlsErrors(emitEvent: boolean): void {
(this as {status: string}).status = this._calculateStatus();
...And |
c5827ba to
02b997b
Compare
AndrewKushnir
left a comment
There was a problem hiding this comment.
Thanks for the updates @benbraou 👍
I've left a few comments, please have a look.
Also I wanted to mention that I ran tests in Google's codebase and there are few cases where additional investigation is needed. I will keep you updated.
Thank you.
There was a problem hiding this comment.
I really like the new validator, which has just the necessary logic, i.e. timeout and whether validation should be successful or not 👍 It'd be great to use the same validator for the FormControl as well, so it's consistent:
const c = new FormControl('fcValue', null!, simpleAsyncValidator({timeout: 10, shouldFail: false}));
const g = new FormGroup({'one': c}, null!, simpleAsyncValidator({timeout: 20, shouldFail: true}));
There was a problem hiding this comment.
Sounds good. I am now using asyncValidator for all the tests that I added.
Please let me know if I also should refactor the existing tests to use the new validator as well. Maybe this can be done in a separate commit or separate PR, or just wait :)
There was a problem hiding this comment.
Let's make a refactor in a separate PR. I believe we may also need to look into combining asyncValidator and simpleAsyncValidator in tests.
There was a problem hiding this comment.
That makes sense. Thank you!
4d2cf6e to
ae9e2f6
Compare
AndrewKushnir
left a comment
There was a problem hiding this comment.
The change looks good, thanks @benbraou 👍
I left a couple comments, please have a look when you get a chance. I'd also propose adding some tests to cover basic cases of the FormArray class (with FormControls and FormGroups), what do you think?
Also a quick update: tests in Google's codebase went well. I'll re-run them again once all the changes are finalized.
c845a21 to
c76a9a4
Compare
|
@AndrewKushnir thank you for the continuous review and help. I have fixed the typos |
|
Hi @benbraou, thanks for the fixes 👍 Tests in Google's codebase resulted in a couple failures. After further investigation it turned out that my proposal to reuse the So what'd happen in this case is that the callback function would be invoked synchronously and at that time the So I think we should go back to your original approach of having a boolean flag (we can reuse the We can probably include this logic into the Sorry that my proposal turned out to be incorrect (thus we have to make this extra iteration) and thanks for all your help with this PR! Please let me know if any additional information is required. Thank you. |
|
@AndrewKushnir No problem, Thank you! I really appreciate the detailed explanations throughout the PR. That's very educational 👍 it('should handle failing async FormGroup and failing child control validators resolving synchronously',
fakeAsync(() => {
const c = new FormControl(
'fcValue', null!, simpleAsyncValidator({timeout: 0, shouldFail: true}));
const g =
new FormGroup({'one': c}, null!, simpleAsyncValidator({timeout: 0, shouldFail: true}));
// FormControl async validator has executed and failed synchronously with the deafult error
// `{async: true}`. Next, the form group status is calculated. Since one of its children is
// failing, the form group itself is marked `INVALID`. And its asynchronous validation is
// not even triggered. Therefore, we end up with form group that is `INVALID` but whose
// errors are null(child error do not propagate and own async validation not event
// triggered)
expect(currentStateOf([g, g.get('one')!])).toEqual([
{errors: null, pending: false, status: 'INVALID'}, // Group
{errors: {async: true}, pending: false, status: 'INVALID'}, // Control
]);
}));The comments should be clear, but basically, I was expecting the form group to have its own errors in its status. updateValueAndValidity(opts: {onlySelf?: boolean, emitEvent?: boolean} = {}): void {
....
if (this.status === VALID || this.status === PENDING) {
this._runAsyncValidator(opts.emitEvent);
}
...
}Anyway, if this behaviour should be changed, I think this is not linked to the original issue that this PR is solving |
AndrewKushnir
left a comment
There was a problem hiding this comment.
Hi @benbraou, thanks for applying additional changes and adding extra tests 👍
I've looked at the changes again and left a few minor comments, mostly related to formatting (extra/missing line, etc). The changes LGTM, so I'm approving this PR. I will add the "cleanup" label that I will remove once the mentioned formatting comments are addressed.
Also an update after running tests in Google's codebase: all tests are passing (external link), which is great!
I have just one remark regarding this new test that I added:
I looked at the test and at the comment, everything looks reasonable to me, thanks for adding a description of this situation in the test itself.
Thank you.
|
Hi @AndrewKushnir, I have addressed the remaining comments. |
introduce a boolean to track form groups/arrays own pending async validation to distinguish between pending state due to children and pending state due to own validation Fixes angular#10064
6ebac58 to
a83fcc1
Compare
|
Thanks for addressing the feedback @benbraou. FYI, I've rebased your PR on top of the current master, since CI was "red" (since PR was not rebased recently). As I mentioned in my previous message, running tests in Google's codebase didn't indicate any issues (including a global run in Google's codebase). Also given the fact that this is a bug fix with low risk, I'm removing the "breaking changes" flag. In any case, since the behavior of the framework changes slightly (to become more accurate), we would merge it to master only and it will be released as a part of the next minor version (v10.1.0). Thank you. |
|
Great news. Thank you ! |
|
Hi @benbraou, just wanted to let you know that your PR is now merged to master and the changes should be available in Please let me know if you might be interested in doing some further refactoring around async validators in the tests (to reuse one async validator across multiple test cases). Thank you. |
|
@AndrewKushnir thank you! Yes, I am interested to continuing the refactoring in tests. Can you please let me know if you want me to create a new issue for this? |
|
Hi @benbraou, thanks for the reply. Yes, I think creating a new ticket would be great, thanks. I was thinking if we can extract common validators code into a new
Please let me know if any additional information is required, I'll be glad to help. Thank you. |
|
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
…ngular#22575) introduce a boolean to track form groups/arrays own pending async validation to distinguish between pending state due to children and pending state due to own validation Fixes angular#10064 PR Close angular#22575
introduce a boolean to track form groups/arrays own pending async validation to distinguish between pending state due to children and pending state due to own validation
Fixes #10064
PR Checklist
Please check if your PR fulfills the following requirements:
PR Type
What kind of change does this PR introduce?
What is the current behavior?
Scenario:
form control/ arrayform control/ arrayvalidator has not resolved yetCurrently, the
form control/arrayis considered valid even if its own validator has not resolved yetIssue Number: N/A
#10064
What is the new behavior?
The
form control/arrayis in pending state if its own validator has not resolved yet and none of its children is invalidDoes this PR introduce a breaking change?
Other information