Why does [disabled]="canDisable" will not work for Angular2 reactive forms

Mahesh Bongani picture Mahesh Bongani · Oct 17, 2017 · Viewed 7.6k times · Source

I'm trying to disable a reactive input form control in angualr2 as disabled based on a variable "canDisable" from the component. My code looks something like this.

<input type="text" formControlName="CustomerName" Name="CustomerName" 
[disabled]="canDisable"/>

Unfortunately, it is not working as expected can anyone provide me the reason for it.

However, it is working fine If I do [attr.disabled]="canDisable".

   <input type="text" formControlName="CustomerName" Name="CustomerName" 
    [attr.disabled]="canDisable"/>

Answer

Daniel Kucal picture Daniel Kucal · Oct 17, 2017

After short investigation I've found out that setting disabled input in FormControl causes ReactiveErrors.disabledAttrWarning():

It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
you. We recommend using this approach to avoid 'changed after checked' errors.

  Example: 
  form = new FormGroup({
    first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
    last: new FormControl('Drew', Validators.required)

According to this comment it seems like another official solution for doing this is invoking FormControl.disable() method manually and the mentioned reason is again about change detection. I agree it can be considered as a bug... And there is also some explanation about it in angular/material2 repository: https://github.com/angular/material2/issues/2667#issuecomment-275280698

As you can see in the docs: Disabled controls are exempt from validation checks and are not included in the aggregate value of their ancestor controls. - maybe this is another reason to do it explicitly.