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

Reactive forms, async validator issue with delayed observable #44295

Open
Maryannah opened this issue Nov 28, 2021 · 9 comments
Open

Reactive forms, async validator issue with delayed observable #44295

Maryannah opened this issue Nov 28, 2021 · 9 comments
Labels
area: forms P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Milestone

Comments

@Maryannah
Copy link

Maryannah commented Nov 28, 2021

Which @angular/* package(s) are the source of the bug?

forms

Is this a regression?

No

Description

Everything can found here :

https://stackblitz.com/edit/angular-ivy-paseta?file=src/app/app.component.ts

Explanation :

When using an async validator with a delayed observable, in a reactive form, with the change detection set to OnPush, the UI does not get updated after the validator has ended its call.

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-ivy-paseta?file=src/app/app.component.ts

Please provide the exception or error you saw

No exception, no error, just the UI not updating correctly

Please provide the environment you discovered this bug in (run ng version)

All can be found on the provided stackblitz

Anything else?

Screenshots for the lazy ones out there :

First blur :

image

Second blur :

image

@ngbot ngbot bot added this to the needsTriage milestone Nov 29, 2021
@shashanksingh91
Copy link

Hi @Maryannah ,
I have tried your problem.

**Solution : **
Found one solution if you remove the updateOn: 'change' code from the form method it will work fine.

Reason :
I found that if we add a Async Validator by default it updates the control on on blur, but yes even if we are adding it explicitly why it is not working that is still a question.

Working Code
form = this.fb.group({ test: [ '', { validators: [Validators.required], asyncValidators: [this.testFn.bind(this)], }, ], });

@Maryannah
Copy link
Author

The update on change is there for a reason ... I'm not asking to find a workaround, I know how to do that in at least 3 different ways.

What I'm doing is raising a bug on change detection which is not supposed to happen, since everything is scoped in the angular context.

@Maryannah
Copy link
Author

Hello, any news on that matter ?

@MatusKnizka
Copy link

MatusKnizka commented Jan 20, 2022

Hello @Maryannah , I think your problem might be in OnPush change detection strategy. During OnPush, there is no change detection performed once your async error is resolved.

Would it be okay for you to remove row changeDetection: ChangeDetectionStrategy.OnPush, ?

Another solution (more complex) would be to manually trigger detection, once your asyncValidator is done with validation.

@Maryannah
Copy link
Author

Hello,

I know this is the issue. What I am saying is that it should NOT be an issue. I am running inside Angular's context, which is supposed to be "synced" with the UI. Hence, updating the validation state of a form control should update the UI accordingly.

As said, I know how to work around this issue, which I have done (by triggering change detection myself, indeed). What I am asking is to NOT use a workaround, because of the aformentioned reason.

@alxhub alxhub added the P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent label Nov 16, 2022
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Nov 16, 2022
@ahoss63
Copy link

ahoss63 commented May 12, 2023

Hello,
i think a good solution is to inject cdr in the component then call markForCheck inside a finalize operator like this :
finalize(() => { this.cdr.markForCheck(); })
here is a fork for that
https://stackblitz.com/edit/angular-ivy-mhabvz?file=src%2Fapp%2Fapp.component.ts

@Maryannah
Copy link
Author

Hi,

I don't know what isn't clear in my previous messages, so I will try another language just in case :

Je sais déjà comment contourner le souci, je ne cherche donc pas un moyen de contourner le souci, mais de le résoudre entièrement, car e problème ne devrait pas arriver de base.

@blazkovicz
Copy link

blazkovicz commented May 16, 2023

I have the same problem:

  1. OnPush
  2. async validator on the field
  3. onChange: 'blur' to avoid running validation on every keydown
  4. on first blur validation is not shown, on second blur is shown
    * with onChange: 'change' validation is shown on first blur (I guess, only when it is fast enough to get result before blur)

I do not understand why this quite basic functionality contains such a bug, while OnPush considered to be more optimized way to organize component flow.

P.S. angular v15. Correct me if v16 has it fixed, but this issue is still open.

P.P.S. for me decent workaround is to watch form pending state change from true to false and trigger markForCheck on component, cos validation is defined as a common utility method.

P.P.P.S. this is so frustrating to copy-paste same logic into every form with async validation: setup pending watcher in onNgInit, check pending on submit and setup waiter for autoretry if form becomes valid after pending

@ManuelOverdijk
Copy link

Any updates since May this year?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: forms P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

No branches or pull requests

8 participants