Home > Net >  Angular 11 structural directive breaks when compiling via AOT
Angular 11 structural directive breaks when compiling via AOT

Time:12-15

I am attempting to migrate from Angular 8 to 11.

I have gotten everything to work except for a custom directive. The directive works when running the app using ng serve, but breaks when compiled with the --aot or --prod flags. The browser console log reports the following error:

core.js:10073 NG0303: Can't bind to 'hasPermission' since it isn't a known property of 'span'.

where hasPermission is the directive, and span is any element I attempt to use the directive. This used to work fine in Angular 8.

The directive itself:

import { Directive, OnInit, Input, ElementRef, TemplateRef, ViewContainerRef } from '@angular/core';


@Directive({
  selector: '[hasPermission]',
})
export class PermissionsDirective implements OnInit {

  constructor(
    private element: ElementRef,
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
  ) {}

  ngOnInit() {
    ...
  }

  // this is the structural call we're looking for
  // the directive will respond to *hasPermission="'perm'"
  @Input('') 
  set hasPermission(value: any) {
   ...
  }
}

it is declared and exported using a SharedModule:

@NgModule({
  declarations: [
   ...
   PermissionsDirective,
   ...
  ],
  exports: [
   ...
   PermissionsDirective,
   ...
  ]
})

export class SharedModule {}

and finally, it's used in many other modules/components like so:

some.module.ts
import { SharedModule } from 'path/shared.module';
@NgModule({
 imports: [
  SharedModule,
 ],
 declarations: [
  SomeComponent
 ]
})

somehtml.html
...
<div *hasPermission="'somepermission'">...</div>
...

some.component.ts
@Component({ templateUrl: 'somehtml.html' })...

I'm thinking this has something to do with the -aot flag not placing modules in the right place so that they're visible? Otherwise I don't understand why there are no issues using just ng serve

Minimal example shown here: https://stackblitz.com/edit/angular-ivy-rzu5jm?file=src/app/app.component.html

Browser console for the stackblitz shows the same error (NG0303)

CodePudding user response:

The issue is with @Input(''). You should not set anything inside the decorator, or if you do it needs to have the same name, that if you want to name it as an alias. Removing the empty string should fix it:

@Input()
set hasPermission(value: any) {
  console.log(value);
}

FORKED STACKBLITZ

CodePudding user response:

You must remove the rename from the decorator @Input('') -> @Input()

@Input() 
set hasPermission(value: any) {
  ...
}
  • Related