In my Angular 7 project, I am utilizing TypeScript to implement two data tables on a single page. Each table requires a rerender method in order to incorporate a search bar functionality. While the data tables come with built-in search bars, the sheer volume of rows in the data arrays significantly hampers the performance. By filtering the array through a search bar, I can enhance the speed and efficiency of the data tables.
For a single table, I have successfully implemented the rerender process using dtElement, dtInstance.destroy(), and dtTrigger.next(). However, when attempting to extend this functionality to two tables, I encountered an error referencing DataTables: "Cannot reinitialize DataTable." This error led me to a forum where I found code that relied on jQuery, which I am not using. Here is the problematic code snippet:
This representation illustrates Table 1:
<input type="text" class="form-control" placeholder="Search for a code from SAT catalog" (change)="searchCodeProdServ()" [(ngModel)]="searchCodeProdServ">
<div class="table-responsive table-wrapper-scroll-y">
<table id="tableCodeProdServ" datatable [dtOptions]="dtOptions['new']" [dtTrigger]="dtTrigger['new']" class="table table-hover">
<thead>
<tr>
<th scope="col">Code</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr class="pointer" *ngFor="let item of listCodeProdServ;">
<td scope="col">{{item.code}}</td>
<td scope="col">{{item.description}}</td>
</tr>
</tbody>
</table>
</div>
This illustration represents Table 2 (nearly identical, except for the data array used):
<input type="text" class="form-control" placeholder="Search for a code from SAT catalog" (change)="searchUnitCode()" [(ngModel)]="searchUnitCode">
<div class="table-responsive table-wrapper-scroll-y">
<table id="tableUnitCode" datatable [dtOptions]="dtOptions['new']" [dtTrigger]="dtTrigger['new']" class="table table-hover">
<thead>
<tr>
<th scope="col">Code</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody>
<tr class="pointer" *ngFor="let item of listUnitCodes;">
<td scope="col">{{item.code}}</td>
<td scope="col">{{item.description}}</td>
</tr>
</tbody>
</table>
</div>
Here is a snippet from my TypeScript file:
export class FrmRegisterProductComponent implements AfterViewInit, OnDestroy, OnInit {
//data arrays
listCodeProdServ: Array<GenericModel>;
listUnitCodes: Array<GenericModel>;
//search terms
searchCodeProdServ: string;
searchUnitCode: string;
@ViewChildren(DataTableDirective)
dtElements: QueryList<DataTableDirective>;
dtOptions: DataTables.Settings[] = [];
dtTrigger: Subject<any>[] = [];
constructor(private lists: GenericList) {
}
ngOnInit(): void {
this.dtTrigger["new"] = new Subject<any>();
this.dtOptions['new'] = {
pagingType: 'full_numbers',
language: this.lists.dtEspanol,
searching: false
};
this.listCodeProdServ = [];
this.listUnitCodes = [];
}
ngAfterViewInit(): void {
this.dtTrigger['new'].next();
}
ngOnDestroy(): void {
this.dtTrigger['new'].unsubscribe();
}
rerender():void{
this.dtElements.forEach((dtElement: DataTableDirective) => {
dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
this.dtTrigger['new'].next();
});
});
}
//search methods
searchCodeProdServ():void{
this.listCodeProdServ = this.lists.CodeProductService.filter(o => o.description.includes(this.searchCodeProdServ));
this.rerender();
}
searchUnitCode():void{
this.listUnitCodes = this.lists.UnitCode.filter(o => o.description.includes(this.searchUnitCode));
this.rerender();
}
}
I also attempted surrounding dtTrigger with setTimeout(()=>{...}); without success.
If anyone could offer assistance, I would greatly appreciate it. Thank you for reading this far.