1

I'm trying to dynamically populate a table with custom components that works perfectly with JIT compilation but throws an error when using AOT.

I've also tried using forwardRef on the ViewChildren() decorator but it doesn't seem to have any effect. My guess is that the service used for selecting the certain DOM elements is not available at that point in time.

Any clues or suggestions?

Error:

> ./node_modules/.bin/ng serve --aot

ERROR in : Can't construct a query for the property "cellList" 
of "ListComponent in example-angular-app/dist/table/table.d.ts" 
since the query selector wasn't defined.

Code:

export class ListComponent implements OnInit, AfterViewChecked, OnDestroy {
    isAlive = true;

    @ViewChildren(CellContainerDirective, { read: ViewContainerRef }) cellList: QueryList<ViewContainerRef>;

    config: Config;
    isLoading: boolean;

    constructor(
        private componentFactoryResolver: ComponentFactoryResolver,
        private cdRef: ChangeDetectorRef
    ) { }

    ngAfterViewChecked() {
        this.cdRef.detectChanges();

        this.cellList.changes
            .pipe(takeWhile(() => this.isAlive))
            .subscribe((list) => {
                list.forEach((cellContainer: ViewContainerRef, index: number) => {
                    cellContainer.clear();

                    const columnIndex = index % this.config.columns.length;

                    const componentFactory = this.componentFactoryResolver
                        .resolveComponentFactory(this.config.columns[columnIndex].cellComponentType);

                    const componentRef = cellContainer
                        .createComponent(componentFactory);

                    const component = <ICellComponent>componentRef.instance;

                    Object.assign(component, {
                        data: this.list.results[columnIndex],
                        column: this.config.columns[columnIndex]
                    });
                });
            });
    }
}

Template:

    <tbody *ngIf="list?.total > 0">
        <ng-container *ngFor="let item of list.results;">
            <tr>
                <td *ngFor="let col of config.columns;">
                    <ng-container cell-container></ng-container>
                </td>
            </tr>
        </ng-container>

        <ng-template #whenEmpty>
            <tr class="empty">
                {{ config?.texts?.table.noData | async }}
            </tr>
        </ng-template>
    </tbody>
Andrei Pit
  • 21
  • 6

1 Answers1

1

Issue has been fixed, instead of using cell-container directive, I've created a custom component to act as a container and directly selected the said component via @ViewChildren(ContainerComponent) instead of @ViewChildren(CellContainerDirective)

Andrei Pit
  • 21
  • 6