angular: formGroup disable()/enable() does not work right after init
I’m submitting a…
[x] Bug report
Current behavior
I you create a formGroup
using formBuilder.group()
and call formGroup.disable()
or formGroup.enable()
right after initialization then it doesn’t work.
If you call it using button
or setTimeout()
then it works.
Expected behavior
Would be nice to be able to disable/enable form right after creation.
Minimal reproduction of the problem with instructions
View: https://ng-form-disable-after-init.stackblitz.io Edit: https://stackblitz.com/edit/ng-form-disable-after-init
Environment
Angular version: 5.2.7
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 66
- Comments: 42 (3 by maintainers)
Commits related to this issue
- fix(forms): not picking up disabled state if group is swapped out and disabled Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doesn't actu... — committed to crisbeto/angular by crisbeto 3 years ago
- fix(forms): not picking up disabled state if group is swapped out and disabled Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doesn't actu... — committed to crisbeto/angular by crisbeto 3 years ago
- fix(forms): not picking up disabled state if group is swapped out and disabled Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doesn't actu... — committed to crisbeto/angular by crisbeto 3 years ago
- fix(forms): not picking up disabled state if group is swapped out and disabled Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doesn't actu... — committed to crisbeto/angular by crisbeto 3 years ago
- fix(forms): not picking up disabled state if group is swapped out and disabled Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doesn't actu... — committed to crisbeto/angular by crisbeto 3 years ago
- fix(forms): not picking up disabled state if group is swapped out and disabled (#43499) Fixes a long-standing issue where swapping out the `FormGroup` and calling `disable` immediately afterwards doe... — committed to josmar-crwdstffng/angular by crisbeto 3 years ago
Same issue on 8.2.14
Version 8 is about to drop…is this bug going to be addressed? I noticed that the severity of this bug is marked as ‘inconvenient’. I wouldn’t say that it’s inconvenient. It essentially breaks the first precept of reactive forms where they are supposed to be synchronous. Somehow a race condition is occurring in ‘synchronous’ code.
I am having the same issue, here is a summary of my setup:
component.ts
component.html
Changing
this.disabledGroup.disable()
tosetTimeout(() => this.disabledGroup.disable());
works as expected.ng version
another workround for this issue is to call detectChanges() before .disbale()/.enable() operations.
This simple directive works for me:
Tested on Angular@6.0.5
UPDATE: Fix calling enable/disable loop
Same issue on 8.1.3 ! Guys, this issue has been opened almost 2 years ago, come on !
I was having an issue that may be related, thought I’d share for everyone, might help the Angular team. My form component is subscribing to a subject on its parent component, and is supposed to disable itself when the parent is communicating with the server. The subscription happens in ngOnInit, but the actual call to disable() does not happen until the user clicks submit and the client starts communicating with the server, so I thought this issue was unrelated.
After days of frustration, I decided to throw the timeout line into my code, but neglected to remove the old line calling disable(). Bam, it worked! So I go take out the old line, and it no longer worked. That’s when I discovered that you have to double-call disable() to get it to work.
Crazy. This is made even more strange by the fact that I use this method for another form with basically the exact same code, and it works.
I Have the same issue, you can find a minimal working example here
Environment Angular version: 6.1.0
Same issue here.
I am as well: I have a class that extends
FormGroup
, where in the constructor it just callssuper({...})
to populate the form, then callsdisable()
.If I dispatch a new instance of this object to the state, the form in the UI does not render as I’d expect (if the old form was enabled, the fields will still be enabled).
If I wrap the
.disable()
line in asetTimeout()
, then it works as you’d expect.Also reporting this problem on 8.2
Bump. Same problem with angular 8
Any plan to fix in ReactiveFormModule? this set Timeout solution is annoying since purpose of reactive form is to keep things synchronous.
for the note purpose, this one work for me:
@maxime1992
the solution on this comment https://github.com/angular/angular/issues/22556#issuecomment-501670796 works 😃 this is what i am using for more than 2 years 📦
Working example here.
note 1:
setTimeout
can broke tabbing the form controls in some cases** (accesibility) avoid it if you can.note 2: Also another option that i never had to use is to don’t rebind a new reference of form but create a reInit methode That reset each control from the current form and clean it’s state/status. You need to tweek the way you create it to simplify the reinit if you want to do it this way…
note 3:
detectChanges
from the doc https://angular.io/api/core/ChangeDetectorRefso it’s pretty fine to use it if you have a form component with it’s children* (use
detach
/on_push
if needed)@maxime1992 I am debugging angular code base to understand where in the lifecycle it rebind it to evaluate the
disabled
but to be honest the other issue about ‘readOnly’ is far more important to fix in my opinion so i prefer to check the readonly first 😛 (the one you posted a big text)Same issue 11.0.7
That’s works for me.
One way I found that fixes this is if your component is using an @Input, then you can set the disabled() in the ngOnChanges after firstChange.
It worked with me after call .enable() inside settimeout
setTimeout(() => { this.OTPForm.enable(); }, 1000);
Same Issue here, maybe one day this will be fixed…
Solved this issue with
Thanks @rcpp0 but I doubt that’s the case.
The issue is happening on a library we built at work: https://github.com/cloudnc/ngx-sub-form
It does work on most of the forms but for some reason, for some of them it doesn’t work 🤷♂️. I couldn’t figure out why.
The way the library works to manage sub forms is for every control value accessor we create an internal form group that represents the sub form and here’s how the
setDisabledState
is handled:So if working for one, no sign of weird behavior indicating that it shouldn’t work for others here IMO.
After digging into this issue on the library, I found out that within the hook
writeValue
of the control value accessor, we are doing:The fix is actually as simple, weird and unexpected as:
If I console.log before and after the
setValue
the value ofthis.formGroup.disabled
it’s always the same which makes even less sense to me as if there’s an actual bug I thought it would be disabled before and enabled after we update the value. But it’s not case even though the fix seems to point in the opposite direction 🤷♂️I found one solution, without setTimeout and extra directives. Try to put this into your form elements:
[attr.disabled]="formGroup.controls['userName'].disabled"
Try to bind the inputs with [formControl]=“form.controls[‘controlName’]” insted of formControlName
I have version 8 but still same issue
@lppedd I’ve noticed that when I’m debugging and the app becomes really slow. Add this check in the directive solves my problem
I’ve updated my directive, resolving the enable/disable methods calling infinite loop! 😃