I am currently using "tabulator-tables" version 4.9.3 for a React application.
One of the requirements for this project is to receive live-stream data from a websocket which contains a mix of existing rows to be updated and new rows to be added.
In order to accomplish this, whenever I receive a new piece of data from the websocket, I check within componentDidUpdate() to see if this.props.data has changed and then use the updateOrAddData() function provided by tabulator to update the table accordingly.
componentDidUpdate(prevProps) {
const { data } = this.props;
if (data !== prevProps.data) {
this.table.updateOrAddData([data]);
}
}
As the table is populated with data coming from the websocket, I have noticed that Tabulator's embedded sorting algorithm is not called to determine the correct sorting position for the new data being added to the table by updateOrAddData(). If the user does not explicitly click a column header to re-sort this data, the data will be out of order based on the condition provided by the user.
What I have tried:
One possible solution that I tried was to utilize the returned promise from updateOrAddData() and call setSort() manually.
const { data } = this.props;
this.table.updateOrAddData(data).then(() => {
const sorters = this.table.getSorters();
this.table.setSort(sorters);
});
Unfortunately, whenever setSort() is called, the scrollbar returns to the top of the table, thus making it difficult to scroll throughout the table since new data is received approximately every second.
In order to demonstrate this problem, I have replaced the websocket connection with a setInterval() function which randomly generates data every second.
The code that I am currently using can be accessed at https://codesandbox.io/s/currying-brook-ck8r3 or below.
Code:
import React, { Component, createRef, useEffect, useState } from "react";
import Tabulator from "tabulator-tables";
import "../node_modules/tabulator-tables/dist/css/tabulator.min.css";
class TabulatorTable extends Component {
constructor(props) {
super(props);
this.el = createRef();
this.table = null;
}
componentDidMount() {
const { columns, options } = this.props;
this.table = new Tabulator(this.el, {
columns,
data: [],
...options
});
}
componentDidUpdate(prevProps) {
const { data } = this.props;
if (data !== prevProps.data) {
this.table.updateOrAddData([data]);
}
}
render() {
return <div ref={(el) => (this.el = el)} />;
}
}
const App = () => {
const [mockWsData, setMockWsData] = useState({});
const columns = [
{
field: "id",
title: "ID",
sorter: "number"
},
{
field: "letters",
title: "Random letters",
sorter: "string"
}
];
const options = {
height: "500px",
index: "id",
layout: "fitColumns",
reactiveData: true
};
useEffect(() => {
const generateFakeData = setInterval(() => {
setMockWsData({
id: Math.floor(Math.random() * Math.floor(15)),
letters: Math.random().toString(36).substring(2, 7)
});
}, 500);
return () => clearInterval(generateFakeData);
}, [setMockWsData]);
return (
<TabulatorTable columns={columns} data={mockWsData} options={options} />
);
};
export default App;
question from:
https://stackoverflow.com/questions/65945239/tabulator-does-not-re-sort-data-after-adding-updating-row