I am fetching data from API using Axios and storing that into a react state variable.
Then, in my render method, I am trying to destructure that fetched data( which is a nested array of objects) into linear form and using it in my react-table.
this is the structure of the fetched data:
[
{ "uuid": "c47dea20",
"siteName": "dfsf",
"systemName": "bl",
"measurementName": ",nk",
"statistics": {
"dateStart": "2020-04-20T00:00:00Z",
"dateStop": "2020-04-21T00:00:00Z",
"values": [
"temperature1",
"temperature2"
],
"min": [1, 2],
"max": [10, 11],
"average": [5, 6],
"last": [7, 8],
"bucket_size": "4h",
"buckets": {
"term": "count",
"values": [5,4,4,5,6,6]
}
}
}
]
This is how I am trying to destructure:
// gives error: TypeError: Cannot read property 'buckets' of undefined
const {
measurementsData: {
statistics: {
buckets: [{ values: bucketValues }],
},
},
} = this.state;
console.log(bucketValues);
Below is the complete code of my component:
class Table extends Component {
constructor(props) {
super(props);
this.state = {
measurementsData: [],
isLoading: false,
dropdownOpen: false,
};
}
signal = axios.CancelToken.source();
componentDidMount() {
this.handleGetmeasurementsDataInfo();
this.addFilterPlaceholder();
}
componentWillUnmount() {
this.signal.cancel("Api is being canceled");
// fix Warning: Can't perform a React state update on an unmounted component
this.setState = (state, callback) => {
return;
};
}
handleGetmeasurementsDataInfo = async () => {
this.setState({ isLoading: true });
await axios
.get("https://run.mocky.io/v3/d2f89c5b-487f-409c-bf2c-705b7d91e12d")
.then((response) => {
// handle success
console.log("measurement data:", response.data);
this.setState({ measurementsData: response.data });
})
.catch((error) => {
// handle error
if (axios.isCancel(error)) {
console.log("Unable to fetch measurementsData", error.message);
} else {
this.setState({ isLoading: false });
}
});
};
addFilterPlaceholder = () => {
const filters = document.querySelectorAll("div.rt-th > input");
for (let filter of filters) {
filter.placeholder = "Search..";
}
};
toggleDropdown = () => {
this.setState((state) => {
return {
dropdownOpen: !state.dropdownOpen,
};
});
};
render() {
const { dropdownOpen, measurementsData } = this.state;
// gives error: TypeError: Cannot read property 'buckets' of undefined
const {
measurementsData: {
statistics: {
buckets: [{ values: bucketValues }],
},
},
} = this.state;
console.log(bucketValues);
return (
<>
<div className="content">
<Row className="mt-5">
<Col xs={12} md={12}>
<Card>
<CardHeader>
<CardTitle tag="h4">heading</CardTitle>
<hr />
<Dropdown isOpen={dropdownOpen} toggle={this.toggleDropdown}>
<DropdownToggle caret>Ships</DropdownToggle>
{measurementsData.map((measurementData) => {
return (
<DropdownMenu key={measurementData.siteName}>
<DropdownItem>
{measurementData.siteName}
<DropdownItem divider />
</DropdownItem>
</DropdownMenu>
);
})}
</Dropdown>
</CardHeader>
<CardBody>
<p>static data </p>
<Line data={chartExample9.data} />
<p>dynamic data </p>
<Line data={this.bucketValues} />
<ReactTable
data={[...measurementsData]}
pageSize={
measurementsData.length > 10
? 10
: measurementsData.length
}
filterable
resizable={true}
columns={[
{
Header: "System",
accessor: "systemName",
},
{
Header: "Measurement",
accessor: "measurementName",
},
{
Header: "Value",
accessor: "statistics.values",
},
{
Header: "Min",
accessor: "statistics.min",
},
{
Header: "Max",
accessor: "statistics.max",
},
{
Header: "Avg",
accessor: "statistics.average",
},
{
Header: "Last",
accessor: "statistics.last",
},
{
Header: "Bar",
<Line data={this.bucketValues} />
},
]}
showPaginationTop
showPaginationBottom={false}
className="-striped -highlight"
/>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
);
}
}
export default Table;
UPDATE: updated the destructuring code to below and I now I get "buckets" is undefined
const {
statistics: {
buckets: {
values: [bucketValues],
},
},
} = measurementsData;
console.log(bucketValues);
You already maintain the loading state, use that to return a loader and access the respective variables only after the data is actually available.
Also note that measurementsData is an array and not an object, so you need to destucture it like one. This is assuming the fact that all bucketValues in each measurementsData object will be same
Also the lineData must use
bucketValues
and notthis.bucketValues
since you are not storing this value in class variable