Reputation: 33
The problem here is that, if my new data is fetched from my backend(RestAPI), the datatable does not display the new data even though I called this.setState and if I log the new state, the fetched data gets logged to the console, but is not displayed in my datatable. When I hardcode the data in the constructors this.state = xxx, the data gets displayed just fine. So I think this has to be related to some rerendering problem? I debugged for hours, but I just couldn't find the problem. It would be really great if somebody could help me out here :)
I read very much articles and posts about not rerendering and the lifecycle of react components. As further info, when I log the state in the render method before the return values, it is at first null (as I initialised the state), and after the second rendering the data is in this.state.rowData as desired. But I simply cant find out why it doesnt get displayed in the datatable.
constructor(props) {
super(props);
this.state = {
columnDefs: [{
headerName: "Dump Name", field: "dumpName", sortable: true, filter: true
}, {
headerName: "Type", field: "type", sortable: true, filter: true
}, {
headerName: "Size", field: "length", sortable: true, filter: true
}, {
headerName: "Different CAN-IDs", field: "canIdCount", sortable: true, filter: true
}, {
headerName: "Created At", field: "createdAt", sortable: true, filter: true
}],
rowData: null
}
}
componentDidMount = async () => {
let collectionData = [];
await getSniffs().then(function (sniffdata) {
sniffdata.map(async function (row) {
collectionData.push({
dumpName: row,
length: await getMessageCount(row).then(function (res) {
return res[0].all;
}),
canIdCount: await getIdCountDistinct(row).then(function (res) {
return res[0].count;
}),
createdAt: await getFirstTimestamp(row).then(function (res) {
return res[0].firstTimestamp;
}),
type: "CAN Message"
});
});
}).then(() => this.setState({
rowData: collectionData
}));
};
render() {
console.log(this.state);
return (
<div
className="ag-theme-material"
style={{
height: '500px',
width: '1000px' }}
>
<AgGridReact
// onRowClicked={this.onRowClicked.bind(this)}
columnDefs={this.state.columnDefs}
rowData={this.state.rowData}>
</AgGridReact>
</div>
// : <Loading/>;
)}
}
export default withRouter(SniffOverviewDatatable);
The datatable just shows: No Row to show. At first I think thats the correct result, but it should get updated and show my retrieved data. The logs display exactly the desired data and array-structure.
Thanks for your time and I really hope to get some hints :)
EDIT: Hey hey I just rewrote the componentDidMount function, but it didnt change a thing, im afraid. Data gets logged, but table doesnt get updated :/
Here is the new code of the function (used async/await):
componentDidMount = async () => {
let rowData = [];
try {
const sniffs = await getSniffs();
sniffs.map(async function (row) {
const msgCount = await getMessageCount(row);
const idCount = await getIdCountDistinct(row);
const firstTimestamp = await getFirstTimestamp(row);
rowData.push({
dumpName: row,
length: msgCount[0].all,
canIdCount: idCount[0].count,
createdAt: firstTimestamp[0].firstTimestamp,
type: "CAN Message"
});
});
} catch (e) {
console.log(e);
}
this.setState({
rowData
});
};
Upvotes: 0
Views: 677
Reputation: 33
Hello I just wanted to provide my own answer if anybo0dy looks at this question:
componentDidMount = async () => {
let fetched = await getSniffs();
let rowData = [];
for (const row of fetched.data) {
const msgCount = await getMessageCount(row);
const idCount = await getIdCountDistinct(row);
const firstTimestamp = await getFirstTimestamp(row);
rowData.push({
dumpName: row,
length: msgCount.data[0].all,
canIdCount: idCount.data[0].count,
createdAt: new Date(firstTimestamp.data[0].firstTimestamp),
type: "CAN Message"
});
}
this.setState({
rowData
});
};
This works just fine now :) I also migrated this method one Component above, so the datatable just gets its data via the props and not via state. Thanks and closed!
Upvotes: 0
Reputation: 11
Have you already tried using setState with a callback function and some kind of immutability library such as immutability-helper? This would lead to code like this:
import update from 'immutability-helper';
...
this.setState(prevState => update(prevState, {rowData: {$set: collectionData}});
...
Upvotes: 1