7

As part of an Angular application, I am developing a table based on ag-grid and I want to render a certain cell as an html link.

As I am building the columnDefs dynamically, I would like to avoid hardcoding the cell renderer component (ForeignKeyRendererComponent in the code below) in the column definition.

Unfortunately, I am not able to register the framework components as per the manual: https://www.ag-grid.com/javascript-grid-components/#registering-framework-components

When I do so, I am getting this error:

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

at noComponentFactoryError (core.js:3256)

The only way this works is by referencing the cell renderer component directly in the column definition, like this: cellRendererFramework: ForeignKeyRendererComponent.


My setup & what I have tried:

Angular v6.1.10

ag-grid v21.0.1

module.ts

@NgModule({
  imports: [
    AgGridModule.withComponents([ForeignKeyRendererComponent]),
    ...
  ],
  declarations: [
    ForeignKeyRendererComponent,
    ...
  ],
  entryComponents: [
    ForeignKeyRendererComponent
  ],
});

component.html

<ag-grid-angular style="height: 500px;"
                 class="ag-theme-balham"
                 [context]="context"
                 (gridReady)="onGridReady($event)"
                 [gridOptions]="gridOptions"
                 [frameworkComponents]="frameworkComponents"
                 [rowData]="rowData"
                 [columnDefs]="columnDefs"
                 rowSelection="multiple"
                 pagination=true
                 paginationPageSize=10>
</ag-grid-angular>

component.ts

  private gridOptions: GridOptions = {
    defaultColDef: {
      filter: true
    },
    animateRows: true,
    isExternalFilterPresent: this.isExternalFilterPresent.bind(this),
    doesExternalFilterPass: this.doesExternalFilterPass.bind(this),
    frameworkComponents: { fkRenderer: ForeignKeyRendererComponent }
  };
...
this.columnDefs.push({
  headerName: translation,
  field: columnNames[index],
  sortable: true,
  filter: customFilter,
  editable: true,
  cellRendererFramework: 'fkRenderer'
});

I have also tried to specify the frameworkComponents independently of the gridOptions: this.frameworkComponents = { fkRenderer: ForeignKeyRendererComponent }, but got the same error.


EDIT: Tried Sean Landsman's suggestion:

Same frameworkComponents definition:

frameworkComponents = { fkRenderer: ForeignKeyRendererComponent };

But with column definition like this:

...
cellRenderer: 'fkRenderer'
...

In this case, I am getting a new error:

custom-error-handler.ts:14 TypeError: Cannot read property 'componentFromFramework' of null at UserComponentFactory.push../node_modules/ag-grid-community/dist/lib/components/framework/userComponentFactory.js.UserComponentFactory.lookupComponentClassDef (userComponentFactory.js:283) at CellComp.push../node_modules/ag-grid-community/dist/lib/rendering/cellComp.js.CellComp.chooseCellRenderer (cellComp.js:632) at new CellComp (cellComp.js:80) at RowComp.push../node_modules/ag-grid-community/dist/lib/rendering/rowComp.js.RowComp.createNewCell (rowComp.js:610) at rowComp.js:594 at Array.forEach () at RowComp.push../node_modules/ag-grid-community/dist/lib/rendering/rowComp.js.RowComp.insertCellsIntoContainer (rowComp.js:587) at RowComp.push../node_modules/ag-grid-community/dist/lib/rendering/rowComp.js.RowComp.refreshCellsInAnimationFrame (rowComp.js:503) at AnimationFrameService.push../node_modules/ag-grid-community/dist/lib/misc/animationFrameService.js.AnimationFrameService.executeFrame (animationFrameService.js:84) at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)

6
  • did you import { ForeignKeyRendererComponent } from '...'; at the top of module.ts? Commented Jun 27, 2019 at 13:33
  • @DavidP.Hochman Yep -- wouldn't build otherwise ;-) Commented Jul 3, 2019 at 8:24
  • I've not seen this error before - if you have a repo (ie plunker or similar) of the problem I'd be happy to take a look Commented Jul 3, 2019 at 10:48
  • @SeanLandsman Thanks for the feedback! I'll try to build a toy project that reproduces this, as right now this occurs in our proprietary code. Commented Jul 3, 2019 at 10:49
  • @SeanLandsman Update: I made a toy project, using your suggestion, and it works. So I think there must be some other factors in my big project that influence this. Your suggestion was the correct one for this problem, however -- thank you! Commented Jul 3, 2019 at 14:43

2 Answers 2

13

There are two ways to register components - by name or by direct reference:

  • By name:
gridOptions or bind to ag-grid-angular directly:
frameworkComponents: {
    countryCellRenderer: CountryCellRenderer
}

columnDefs: [{
   field: 'country',
   cellRenderer: 'countryCellRenderer'
}]
  • By reference:
columnDefs: [{
   field: 'country',
   cellRendererFramework: CountryCellRenderer
}]

In your case I think you're mixing the two - try changing:

cellRendererFramework: 'fkRenderer'

to cellRenderer: 'fkRenderer'

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for your answer! Sorry for the delayed response, had to jump to a different project at work. I have tried your suggestion, now I am getting a new error: "Cannot read property 'componentFromFramework' of null". I have updated my post at the bottom with the full stack trace.
0

I had the same issue, in my case someone (teammate) has used Enterprise filter agSetColumnFilter in columnDefs, I have just changed it to common agTextColumnFilter filter, error disappear

columnDefs = [{ 
        headerName: 'Client',
        field: 'client',
        filter: "agTextColumnFilter",
        // agSetColumnFilter - Enterprise feature
    }];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.