Reputation: 18123
Just as this issue states, if you try to access an ngControl.control with a Directive:
export class DisabledDirective {
@Input()
set opDisabled(condition: boolean) {
const action = condition ? 'disable' : 'enable';
this.ngControl.control[action]();
}
constructor(private ngControl: NgControl) {}
}
You will reach an error upon first rendering:
core.js:5828 ERROR TypeError: Cannot read property 'disable' of undefined
Upvotes: 7
Views: 3202
Reputation: 181
The solution is use the OnChanges lifecycle (as it's mentioned in the official issue)
@Directive({ selector: '([formControlName], [formControl])[disableControl]' })
export class DisableControlDirective implements OnChanges {
@Input() disableControl = false;
ngOnChanges(changes: SimpleChanges) {
if (changes.disableControl.currentValue) {
this.ngControl.control?.disable();
} else {
this.ngControl.control?.enable();
}
}
constructor(private ngControl: NgControl) {}
}
The usage will be like
<input formControlName="id" [disableControl]="true" />
Upvotes: 0
Reputation: 18123
The solution in the given link is quite hacky and unreliable.
Until they fix the issue, simply guard the expression with if-s for the first rendering:
export class DisabledDirective {
@Input()
set opDisabled(condition: boolean) {
const action = condition ? 'disable' : 'enable';
if(this.ngControl?.control){
this.ngControl.control[action]();
}
}
constructor(private ngControl: NgControl) {}
}
ps.: notice the new safe/elvis operator which you can use in Angular 9 in the TS code too :)
Upvotes: 10