I have a component with 3 included components. One of these components is a clickable DataTable (instantiated to an initial value), and upon clicking a new row it emits an output value that is received by the other 2 components, which should update accordingly. I have this functioning properly for graphs involved in the other 2 components, but I cannot get it to re-render a DataTable in one of these components. My data is correct upon each click, but the DataTable seems to be lagged behind by one click (e.g., when I default to State1, no data displays in the table, but when I click into State2, the data from State1 displays, etc.
A large chunk of my code is below (not including some headers). I construct a DataTableDirective that references the relevant HTML (datatable table), specify my Input (emitted from another component not pictured), initialize my dtOptions to an empty DataTable, instantiate my dtTrigger, and then specify relevant methods (ngOnChanges will re-call the API and get new data, which should then be re-rendered into the DataTable).
<div class="card-body text-dark">
<table datatable id="typesTable" class="table table-striped table-bordered display responsive"
style="width:100%" [dtOptions]="dtOptions" [dtTrigger]="dtTrigger"></table>
</div>
export class TypesComponent implements OnChanges {
constructor(private elementRef: ElementRef) { }
@ViewChild(DataTableDirective, {static: false})
dtElement: DataTableDirective;
@Input() stateCounty: string; // format "NY-NewYork"
dtOptions: any = {
data: [
],
columns: [
{title: 'Col1', data: 'Col1'},
{title: 'Col2', data: 'Col2'}
],
order: [['1', 'desc']],
pagingType: 'full_numbers',
processing: true,
dom: 'Bfrtip',
buttons: [ 'csv', 'excel' ],
};
dtTrigger: Subject<any> = new Subject();
async ngOnChanges(changes: SimpleChanges): Promise<void> {
const baseUrl = 'https://baseurl.com';
// make the graph
const state = changes.stateCounty.currentValue.split('-')[0];
const city = changes.stateCounty.currentValue.split('-')[1];
let graph = this.elementRef.nativeElement.querySelector('#timeDiv');
graph.innerText = `Loading...`;
let types = await fetchRetry(baseUrl + `api=${state}&city=${city}`);
types = await types.json();
...
graph.innerText = '';
graph = Plotly.newPlot(graph, data, layout);
...
this.dtOptions = {
data: types,
columns: [
{title: 'Col1', data: 'Col1'},
{title: 'Col2', data: 'Col2'}
],
order: [['1', 'desc']],
pagingType: 'full_numbers',
processing: true,
dom: 'Bfrtip',
buttons: [ 'csv', 'excel' ],
};
this.rerender();
}
ngOnInit(){}
ngAfterViewInit(): void {
this.dtTrigger.next();
}
ngOnDestroy(): void {
this.dtTrigger.unsubscribe();
}
rerender(): void {
try {
this.dtElement.dtInstance.then((dtInstance: DataTables.Api) => {
dtInstance.destroy();
this.dtTrigger.next();
});
} catch (err) {
console.log(err);
}
}
}