Error: HighlightDirective cannot be used as an entry component. NgUpgrade

194 Views Asked by At

I am upgrading my old AngularJS application to Angular using the NgUpgrade module. Upgrading components seems to work ok but I have struggled with getting a directive to work. After I couldnt upgrade my own component I copied the Highlight directive from the Angular tutorials and tried to use that instead.

So, I create the directive, add it to a directives module, then downgrade it for use within AngularJS.

When I do this I get an error:

Error: No component factory found for HighlightDirective. Did you add it to @NgModule.entryComponents?

Ok Mr compiler, no worries, I'll add it to the EntryComponents. Refresh the page and...

Uncaught Error: HighlightDirective cannot be used as an entry component.

Now I am stumped, how do you make this work?

Highlight Directive

@Directive({
    selector: '[highlight]'
})
export class HighlightDirective {
    constructor(el: ElementRef) {
        el.nativeElement.style.backgroundColor = 'yellow';
    }
}

Usage in HTML

<div highlight>

Directives.Module

@NgModule({
    imports: [
        CommonModule,
        MiscDirectivesModule
    ],
    entryComponents: [
        DashboardBoxSmallComponent, // Components work fine, directives do not
        HighlightDirective
    ],
    declarations: [
        DashboardBoxSmallComponent,
        HighlightDirective
    ],
    exports: [
        HighlightDirective
    ]
})
export class DirectivesModule {
    constructor() {
    }
}

Directives.Module.AJS This is where my shiny Angular components are downgraded for AngularJS. The funky downgrade code is from here as apparently "Currently, you cannot downgrade attribute directives.".

const allowAttribute = directiveFactory => [
    '$injector',
    ($injector: angular.auto.IInjectorService) =>
        Object.assign($injector.invoke(directiveFactory), { restrict: 'EA' }),
];

const downgradeAttributeComponent = info => allowAttribute(downgradeComponent(info));

angular
  .module("app.directives", [...])
  .directive("highlight", downgradeAttributeComponent({ component: HighlightDirective }))

App.Module

@NgModule({
    imports: [
        BrowserModule,
        UpgradeModule,
        ServicesModule,
        DirectivesModule, // This is the module shown above
        FiltersModule
    ],
    declarations: [],
    entryComponents: [],
    exports: []
})
export class AppModule {
    constructor(private upgrade: UpgradeModule) {
    }

    ngDoBootstrap() {
        this.upgrade.bootstrap(document.documentElement, [moduleName], { strictDi: true });
    }
}
0

There are 0 best solutions below