angular / angular/angular

Injected ngControl doesn't contain control property in Angular 9

Open
#35,330 11 comments 35 reactions 0 assignees View on GitHub
area: forms P4
Dominant language
TypeScript
Stars
101k
Forks
27.5k
Avg merge
1d 19h
Merged PRs (30d)
288

Description

# 🐞 bug report

### Affected Package

`import { NgControl } from '@angular/forms';`

### Is this a regression?

I believe that this is an Ivy compiler issue

### Description

Injected `ngControl` doesn't contain `control` property in Angular 9.

## 🔬 Minimal Reproduction

```html

{{ 'User.Locked' | translate }}

```

This doesn't work:

```typescript
import { Directive, Input } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
selector: '[opDisabled]'
})
export class DisabledDirective {
@Input()
set opDisabled(condition: boolean) {
const action = condition ? 'disable' : 'enable';
this.ngControl.control[action]();
}

constructor(private ngControl: NgControl) {}
}
```

This works:

```typescript
import { Directive, Input } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
selector: '[opDisabled]'
})
export class DisabledDirective {
@Input()
set opDisabled(condition: boolean) {
const action = condition ? 'disable' : 'enable';
setTimeout(() => this.ngControl.control[action]());
}

constructor(private ngControl: NgControl) {}
}
```

## 🔥 Exception or Error



core.js:5828 ERROR TypeError: Cannot read property 'disable' of undefined

The `control` property is `undefined` and It looks like the it gets appended asynchronously to the injected `ngControl`, that's why the `setTimeout(() => {...})` workaround seems to work. Is this by design or is it a bug?
There is a similar issue reported [#32522](https://github.com/angular/angular/issues/32522), but locked due to inactivity, without any solutions mentioned in the comments.

## 🌍 Your Environment

**Angular Version:**



_ _ ____ _ ___
/ \ _ __ __ _ _ _| | __ _ _ __ / ___| | |_ _|
/ △ \ | '_ \ / _` | | | | |/ _` | '__| | | | | | |
/ ___ \| | | | (_| | |_| | | (_| | | | |___| |___ | |
/_/ \_\_| |_|\__, |\__,_|_|\__,_|_| \____|_____|___|
|___/

Angular CLI: 9.0.1
Node: 13.3.0
OS: darwin x64

Angular: 9.0.0
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, material, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes

Package Version
-----------------------------------------------------------
@angular-devkit/architect 0.900.1
@angular-devkit/build-angular 0.900.1
@angular-devkit/build-optimizer 0.900.1
@angular-devkit/build-webpack 0.900.1
@angular-devkit/core 9.0.1
@angular-devkit/schematics 9.0.1
@angular/cli 9.0.1
@angular/flex-layout 9.0.0-beta.29
@ngtools/webpack 9.0.1
@schematics/angular 9.0.1
@schematics/update 0.900.1
rxjs 6.5.4
typescript 3.7.5
webpack 4.41.2

Contributor guide

Open the contributing guide

Research direction

Start with the NgControl injection path and the DisabledDirective setter shown in the minimal reproduction, then reproduce the failure with Angular 9 and Ivy. Trace when the control property becomes available relative to input evaluation and compare that with the related issue #32522. Done means the timing behavior is confirmed and corrected or documented, with a regression test covering the reproduction.

Written by the indexing model from the issue text.

Assessment

Tech stack
angular, typescript
Domain
frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.