Skip to content

Dependency injection not working for derived classes in ES2015 #12760

Closed
@devversion

Description

@devversion

NOTE: This is a tracking issue!

Consider we have a ES2015 transpiled class for the MatRowDef. The class extends the external CdkRowDef class (which comes from another node module).

material/es2015/table.ts

class MatRowDef extends CdkRowDef {}

MatRowDef.decorators = [SOME_METADATA];
// No MatRowDef.ctorParameters because the "constructor" should be inherited.

cdk/es2015/table.ts

class CdkRowDef {
    constructor(template, _differs) {
        // Does something with template & differ.
    }
}
CdkRowDef.decorators = [SOME_METADATA];
CdkRowDef.ctorParameters = () => [
    { type: TemplateRef, },
    { type: IterableDiffers, },
];

Technically this works within ES2015 applications now. The ReflectionCapabilities from @angular/core are able to properly figure out that MatRowDef is a directive which does not have an explicit constructor, but inherits a constructor from CdkRowDef.

This is being done through a brittle Regular expression that matches ES2015 classes which such traits. See this code snippet from Angular core


But now, if we take the exact same scenario from above and just consider that we run Webpack/ or use the Angular CLI, it won't work at all.

This is because Webpack transforms the ES2015 class into something like that:

Note: This is because CdkRowDef comes from another node module

class MatRowDef extends _angular_cdk_table__WEBPACK_IMPORTED_MODULE_1__["CdkRowDef"] {}

MatRowDef.decorators = [SOME_METADATA];
// No MatRowDef.ctorParameters because the "constructor" should be inherited.

Now: The regular expression (mentioned above) does no longer match the transformed class. Meaning that Angular looks for the ctorParameters on MatRowDef and comes to the conclusion that MatRowDef does not inject anything. So, TemplateRef and IterableDiffers won't be injected, and the table won't work.


A better alternative to the brittle regular expression has been proposed with: angular/tsickle#760. This technically allows the ReflectionCapabilities to drop the regex and just check for ctorParameters to be present. A PR that takes advantage of that new possibility is already pending: See: angular/angular#22642.

This would solve the given problem that is not specific to Angular Material. Everyone that uses the CLI (or explicitly Webpack) may run into a similar issue.

Related: #11580. Related #9329.

Metadata

Metadata

Assignees

Labels

blockedThis issue is blocked by some external factor, such as a prerequisite PR

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions