What is the best way to update multiple data tables using TypeScript?

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.

Answer №1

By setting up individual triggers for each table, I ensure a more organized approach:

<table #table1 datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger1">...

<table #table2 datatable [dtOptions]="dtOptions" [dtTrigger]="dtTrigger2">...

To refresh the tables, the following method is employed:

  dtTrigger1: Subject<any> = new Subject();
  dtTrigger2: Subject<any> = new Subject();

  refreshTables(): void {     
    this.dtElements.forEach((dtElement: DataTableDirective) => {
      if(dtElement.dtInstance)
        dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
          dtInstance.destroy();          
      });
    });
    this.dtTrigger1.next(); 
    this.dtTrigger2.next();    
  }

Achieving success through proper table management!

Answer №2

I managed to fix the issue by including destroy:true in the datatable options section. Make sure to add this line inside your ngOnInit():

ngOnInit(): void {
    this.dtTrigger["new"] = new Subject<any>();
    this.dtOptions['new'] = {
      pagingType: 'full_numbers',
      language: this.listas.dtEspanol,
      searching: false,
      destroy:true // This allows the datatable to be destroyed
    };
    this.listaClaveProdServ = [];
    this.listaClaveUnidad = [];
  }

Answer №3

I encountered a similar issue, but luckily I stumbled upon the solution on GitHub

According to l-lin

The key is to utilize @ViewChildren instead of @ViewChild:

Here is an example code snippet

import { AfterViewInit, Component, OnInit, ViewChildren, QueryList } from '@angular/core';
import { DataTableDirective } from 'angular-datatables';
import { Subject } from 'rxjs/Rx';

@Component({
  selector: 'app-rerender',
  templateUrl: 'rerender.component.html'
})
export class RerenderComponent implements OnInit, AfterViewInit {
  @ViewChildren(DataTableDirective)
  dtElements: QueryList<DataTableDirective>;

  // ...

  rerender(): void {
    this.dtElements.forEach((dtElement: DataTableDirective) => {
      dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
        // Perform necessary actions
      });
    });
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Efficiently loading data in a table with a universal filter feature using Angular with PrimeNG

Recently, I managed to set up a datatable with the functionalities of both Lazy loading and global filter. Utilizing PrimeNG components for this implementation was a breeze. However, an issue surfaced where the global filter ceased to function when lazy lo ...

Universal variable arguments

Is there a way to modify this function that accepts generic rest parameters to also accept an array parameter without using the spread operator? This would make chaining things much clearer: function fn<T>(...args: T[]): Something<T> { } let s ...

Filter an object in Typescript and retrieve a single key

Managing a set of checkboxes is essential in assigning roles to new users. While it's possible to filter and retrieve only the checked checkboxes, extracting just the "name" key poses a challenge. The current method involves filtering with a for loop ...

Obtaining the TemplateRef from any HTML Element in Angular 2

I am in need of dynamically loading a component into an HTML element that could be located anywhere inside the app component. My approach involves utilizing the TemplateRef as a parameter for the ViewContainerRef.createEmbeddedView(templateRef) method to ...

Error: The utilization of the life cycle interface mandates the implementation of type checking

Currently, I am in the process of translating my typescript project to Webpack 2. While one project transitioned smoothly, I encountered an error with the other project... Error: use-life-cycle-interface necessitates type checking After conducting a br ...

Angular 2 Issue: Error Message "Cannot bind to 'ngModel'" arises after FormsModule is added to app.module

I've been struggling with the data binding aspect of this tutorial for over a day now. Here's the link to the tutorial: https://angular.io/docs/ts/latest/tutorial/toh-pt1.html The error I keep encountering is: Unhandled Promise rejection: Tem ...

The JWT Token is not being sent to the allowedDomain or whitelistedDomains in auth0/angular-jwt due to a configuration issue involving Regexp

Currently, I am utilizing the auth0/angular-jwt library to inject JWT tokens into my application. The documentation for this library suggests that configuration can be achieved by using strings or RegExp for specifying allowed domains. However, upon implem ...

Incorporating OpenLayers and TypeScript: Issue with Event.map.forEachFeatureAtPixel, where the argument type is not compatible with the parameter type

I am currently attempting to implement Open Layers v7.2.2 with TypeScript. {When not using TypeScript, the code functions properly} function OnMapClick(event: MapBrowserEvent<UIEvent>) { event.map.forEachFeatureAtPixel(event.pixel, function(curren ...

Leverage a TypeScript property descriptor to substitute the accessors without compromising on composability

Is there a way to create a TypeScript property descriptor that can override accessors and still be easily composed with other functionality? ...

Angular chat fuze template fails to refresh conversation after implementing websocket functionality

In my Angular application, I have implemented a chat service that updates incoming chats in real-time using websockets. The websocket sends me the message and phone number, which I then use to update the chat. updateChatMessages(phoneNumber: string, messa ...

Tips for troubleshooting errors when starting a new Angular project

Journey On my Windows machine, I initially had npm 6.4.1 and node 8.12.0 installed. I decided to upgrade in the following sequence: Started with upgrading npm Then moved on to upgrading node However, now when attempting to create a new app, I encounte ...

Array containing multiple service providers in Angular

I encountered a problem while utilizing multiple providers in my application: ERROR Error: No provider for Array! at injectionError (VM634 core.umd.js:1238) [angular] at noProviderError (VM634 core.umd.js:1276) [angular] at ReflectiveInjector_._throwOrNul ...

Discovering the RootState type dynamically within redux toolkit using the makeStore function

I am currently working on obtaining the type of my redux store to define the RootState type. Previously, I was just creating and exporting a store instance following the instructions in the redux toolkit documentation without encountering any issues. Howev ...

Using ngTemplateOutlet to pass ng-template to a child component in Angular 5

I am looking to develop a versatile component that can utilize custom templates for data rendering, while consolidating the business logic to prevent redundancy. Imagine this use case: a paginated list. The pagination logic should be housed within the com ...

Exploring Angular 4's capability: Incorporating data from Http Post Response into a .js file or highchart

I'm a beginner with Angular 4. I'm trying to create a dashboard that pulls data from an Http Post Response and I want to use this data to create a Chart (Highchart). I have successfully received the response in the console.log and formatted it i ...

Guide on exporting member formModule in angular

After compiling my code in cmd, an error message is displayed: ERROR in src/app/app.module.ts(3,10): error TS2305: Module '"C:/Users/Amir_JKO/my-first-app/node_modules/@angular/forms/forms"' does not have an exported member 'formModul ...

Why am I unable to apply the keyof operator from one type to another type, even though both types have identical keys defined but different value types?

Consider this code snippet. I am encountering a TypeScript error specifically on the last compat[k] line with the following error message: Type 'keyof T' cannot be used to index type 'Partial<CompatType>' export type KeysOfType ...

Guide on implementing Google sign in functionality in Angular 6 and redirecting on successful sign in

Seeking Clarity I recently implemented a component that presents a Google Sign In button to unauthenticated users. Upon signing in, the access token is sent to my server for verification, which then returns a jsonwebtoken. I followed Google's documen ...

Utilizing getter and setter functions within a setter with a type guard

I need to implement a getter and setter in my class. The setter should accept a querySelector, while the getter is expected to return a new type called pageSections. The challenge I'm facing is that both the getter and setter must have the same argum ...

Issue with Props Type Check not functioning as expected in Typescript with React

I am utilizing Typescript within my React application. I aim to rigorously verify the type of props being passed to my components and trigger an error if it does not match. import React from "react"; import styles from "./ServiceDetailCard.css"; type Ser ...