angular-datatables: typeError: Cannot read property 'dtInstance' of undefined - angular2

What versions you are using?

  • angular version:2.4.0
  • jquery version: 3.2.1
  • datatables version: 1.10.15
  • angular-datatables version: 2.3.0
  • angular-cli version: 1.0.0

What’s the problem?

when I try to get instance of Datatable it gives typeError: Cannot read property ‘dtInstance’ of undefined.

Can you share your code?

datatableElement: DataTableDirective;
 dtOptions: DataTables.Settings = {};
 constructor(
 private employeeservice:EmployeeService,
 private route: ActivatedRoute,
 private router: Router,
 ) { 
  this.getEmployee();    
 }
 ngOnInit(): void {
 this.dtOptions = {
  paginationType: 'full_numbers',
  displayLength: 5
  };
 }
displayToConsole(datatableElement: DataTableDirective): void 
{
datatableElement.dtInstance.then((dtInstance: DataTables.Api) => 
console.log(dtInstance));
} 
getEmployee(){
this.employeeservice.getEmployees()
.subscribe(
    employees =>{ 
        this.employees = employees; 
        console.log(this.employees);
    (error:Response) => console.log(error)
  },
 )     
}

 deleteEmployee(employee){
 if (confirm("Are you sure you want to delete Employee ?")) {
 console.log(employee.id);
  var index = this.employees.indexOf(employee);
  this.employees.splice(index, 1);

  this.employeeservice.deleteEmployee(employee.id)
    .subscribe(
      data =>{
        this.emp_data = employee;
      },
      err => {
        alert("Could not delete employee.");
        // Revert the view back to its original state
        this.employees.splice(index, 0, employee);
      },
      () => this.router.navigate(['/employees'])
      );
  }
 }
}

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 1
  • Comments: 31 (7 by maintainers)

Most upvoted comments

Hi, the problem is given by the datatable directive.

In src/angular-datatables.directive.ts in ngInit (line 42) it is possible to see that if dtTrigger is set, the function displayTable is not called until the next method is called on dtTrigger.

So dtInstance will result unavailable until dtTrigger.next(); is called for the first time.

A possible solution is to rewrite the rerender() method in this way:

rerender(): void {
	if("dtInstance" in this.dtElement){
		this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
		  // Destroy the table first
		  dtInstance.destroy();
		  // Call the dtTrigger to rerender again
		  this.dtTrigger.next();
		});
	}
	else{
		this.dtTrigger.next();
	}
}

In your rerender function, use the datatableElement instead of dtElement that is not initialized:

rerender(): void {
    this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
      // Destroy the table first
      dtInstance.destroy();
      // Call the dtTrigger to rerender again
      this.dtTrigger.next();
    });
  }

Unfortunately, you will have to rerender if you want to have your table updated.

I had the same problem, but for some strange reason, I made it work by using a setTimeout:

  @ViewChild(DataTableDirective)
  dtElement: DataTableDirective;

  dtOptions: DataTables.Settings = {};
  products: Product[];
  isLoading = true;
  dtTrigger: Subject<any> = new Subject;

  constructor(
    private route: ActivatedRoute,
    private productService: ProductService
  ) {
    this.route.params.subscribe(params => this.doSearch(params['query']));
  }

  ngOnInit() {
    this.dtOptions = {
      pagingType: 'full_numbers',
      pageLength: 5,
      searching: false
    };
  }

  ngAfterViewInit(): void {
    this.dtTrigger.next();
  }

  doSearch(query: string) {
    setTimeout(() => {
    this.productService.queryProducts(query)
      .pipe(finalize(() => { this.isLoading = false; }))
      .subscribe((products: Product[]) => {
        this.products = products;
        this.rerender();
      });
    });
  }

  rerender(): void {
    this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
      // Destroy the table first
      dtInstance.destroy();
      // Call the dtTrigger to rerender again
      this.dtTrigger.next();
    });
  }

Hi, the problem is given by the datatable directive.

In src/angular-datatables.directive.ts in ngInit (line 42) it is possible to see that if dtTrigger is set, the function displayTable is not called until the next method is called on dtTrigger.

So dtInstance will result unavailable until dtTrigger.next(); is called for the first time.

A possible solution is to rewrite the rerender() method in this way:

rerender(): void {
	if("dtInstance" in this.dtElement){
		this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
		  // Destroy the table first
		  dtInstance.destroy();
		  // Call the dtTrigger to rerender again
		  this.dtTrigger.next();
		});
	}
	else{
		this.dtTrigger.next();
	}
}

This is worked for me but this works too, thank you for this solution

var table = $(“#idTable”).DataTable();
table.destroy(); this.dtTrigger.next();