Skip to content

NG0311: Input/output object literal mapping to array breaks host directive validation #54096

Description

@cyr-x

Which @angular/* package(s) are the source of the bug?

compiler

Is this a regression?

No

Description

When creating a host directive which uses the input/output mapping feature the compiler transforms those mapping into an array which breaks the host directive validation in @angular/core.

Steps to reproduce:

  1. Create a library which contains a directive which defines a host directive and maps it's inputs:
@Directive({
  standalone: true,
  selector: '[appTest]',
  hostDirectives: [
    {
      directive: HostDirective,
      inputs: ['hostInput:testInput'],
    },
  ],
})
export class TestDirective {}
  1. Build the library with partial compilation mode
    The compiler will transform the host directive metadata to:
hostDirectives: [{ directive: i1$1.HostDirective, inputs: ["hostInput", "odxMenu"] }]

export function createHostDirectivesMappingArray(mapping: Record<string, string>):

3. Use the library in another project, the core package will report the NG0311 error.

This is because in @angular/core a validation check fails in when the dev mode is active:

if (!bindings.hasOwnProperty(publicName)) {

Please provide a link to a minimal reproduction of the bug

No response

Please provide the exception or error you saw

NG0311: Directive _a does not have an input with a public name of menu.

at validateMappings (../../../node_modules/@angular/core/fesm2022/core.mjs:14715:23)
at validateHostDirective (../../../node_modules/@angular/core/fesm2022/core.mjs:14700:5)
at Object.findHostDirectiveDefs (../../../node_modules/@angular/core/fesm2022/core.mjs:14616:17)
at findDirectiveDefMatches (../../../node_modules/@angular/core/fesm2022/core.mjs:12727:21)
at resolveDirectives (../../../node_modules/@angular/core/fesm2022/core.mjs:12492:29)

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 16.2.12
Node: 18.18.0
Package Manager: npm 10.3.0
OS: linux x64

Angular: 16.2.12
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router, service-worker

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1602.12
@angular-devkit/build-angular   16.2.12
@angular-devkit/core            16.2.12
@angular-devkit/schematics      16.2.12
@angular/cdk                    16.2.13
@schematics/angular             16.2.11
ng-packagr                      16.2.3
rxjs                            7.8.1
typescript                      5.1.6
webpack                         5.89.0
zone.js                         0.13.3

Anything else?

A possible solution might be to merge the input alias again:

function createHostDirectivesMappingArray(mapping) {
    const elements = [];
    for (const publicName in mapping) {
        if (mapping.hasOwnProperty(publicName)) {
          const mappedPublicName = mapping[publicName];
          const literalName = mappedPublicName === publicName ? publicName : `${publicName}:${mappedPublicName}`;
          elements.push(literal(literalName));
        }
    }
    return elements.length > 0 ? literalArr(elements) : null;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions