Wrap turbotable

UI Components for Angular
Post Reply
glennsymons
Posts: 10
Joined: 06 Dec 2017, 14:59

03 Oct 2018, 11:46

Hi,

How do i wrap the turbotable into my own component? I tried by passing the header and body template as ContentChildren and this works until i add pSortableColumn. Then i get the error:

Code: Select all

TableContainerPageComponent.html:55 ERROR Error: StaticInjectorError(AppModule)[TableBody -> Table]: 
  StaticInjectorError(Platform: core)[TableBody -> Table]: 
    NullInjectorError: No provider for Table!
Is there another way?

Wrapper html:

Code: Select all

<p-table>
<ng-template let-item [pTemplate]="template.name" *ngFor="let template of templates">
    <ng-template *ngTemplateOutlet="template.template; context: { $implicit: item }"></ng-template>
 </ng-template>
</p-table>
Wrapper ts:

Code: Select all

@ContentChildren(PrimeTemplate)
  templates: QueryList<any>;
Usage:

Code: Select all

<fw-table>
    <ng-template pTemplate="header">
      <tr>
        <th [pSortableColumn]="'username'">Gebruikersnaam</th>
        <th >Voornaam</th>
        <th >Achternaam</th>
      </tr>
    </ng-template>

    <ng-template pTemplate="body" let-user>
      <tr [pSelectableRow]="user">
        <td>{{user.username}}</td>
        <td>{{user.voornaam}}</td>
        <td>{{user.achternaam}}</td>
      </tr>
    </ng-template>
  </fw-table>
Greets,
Glenn

glennsymons
Posts: 10
Joined: 06 Dec 2017, 14:59

07 Oct 2018, 16:41

Nobody did this????

cwittied
Posts: 2
Joined: 28 Dec 2018, 17:17

28 Dec 2018, 17:50

I found this post as I was attempting to wrap the turbo table myself, and I also ran into the "No provider for Table!" issue. It turns out this error only appears when one of my templates is using pSortableColumn or pSelectableRow

I really wasn't able to find any help through google, but after 2 days of messing with it I figure out that if I put the 'Table' class into the providers collection of my wrapper component this error went away.

But then I got 'No provider for DomHandler!', so I added this to the providers of my wrapper... then 'No provider for ObjectUtils!', and 'No provider for TableService!'. But after adding all of these to the providers for my wrapper it finally started working.

Code: Select all

import { Table, TableService } from 'primeng/table';
import { DomHandler } from 'primeng/api';
import { ObjectUtils } from 'primeng/components/utils/objectutils';

@Component({
  selector: 'app-data-list',
  templateUrl: './data-list.component.html',
  styleUrls: ['./data-list.component.scss'],
  providers: [Table, DomHandler, ObjectUtils, TableService],
})
export class DataListComponent implements OnInit {
  @ViewChild(('datatable')) datatable: Table;
  @ContentChildren(PrimeTemplate) templates: QueryList<any>;
  ...
}
I just thought I'd reply with this info in case it might save someone else some time.

cwittied
Posts: 2
Joined: 28 Dec 2018, 17:17

31 Dec 2018, 18:22

I wanted to follow up because later in the day I realized this wasn't the correct fix.

While it did get rid of the error, and allow me to pass templates from my parent component into my wrapper component, the pSortableColumn and pSelectableRow directive/components did not work when passed in from the parent component. They worked fine in the default templates that were defined inside the wrapper nested inside the p-table, but not when passed in.

The reasoning is that when I put the Table class into my wrapper's providers list, it simply returns a new instance of a Table to anything that requires it. So the pSortableColumn and pSelectableRow defined outside the wrapper are receiving and working on an empty table that never gets rendered.

I was able to fix this by creating a TableFactory function that requires my wrapper as a dependency. When it's called to provide a Table, it simply provides the Table nested inside the injected wrapper component.

Code: Select all

...
import { DomHandler } from 'primeng/api';
import { Table, TableService } from 'primeng/table';
import { ObjectUtils } from 'primeng/components/utils/objectutils';
...

export function tableFactory(datalist: DataListComponent) {
  return datalist.datatable;
}

@Component({
  selector: 'app-data-list',
  templateUrl: './data-list.component.html',
  styleUrls: ['./data-list.component.scss'],
  providers: [ DomHandler, ObjectUtils, TableService, {
    provide: Table,
    useFactory: tableFactory,
    deps: [DataListComponent]
  }],
})
export class DataListComponent implements OnInit {
  @ViewChild(('datatable')) datatable: Table;
...
}

Episodex
Posts: 1
Joined: 26 Mar 2021, 13:06

26 Mar 2021, 13:09

Hello, I have the same problem and I try to implement your solution, but looks like the factory is invoked too soon in my code (datatable is undefined still). Can you show your template code for the wrapper? Many thanks for sharing your solution!

Post Reply

Return to “PrimeNG”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 32 guests