Reputation: 237
I am developing a page that fetches data from an API and assembles a table using Material UI and Datagrid. My goal to parse data into the Table. My data looks like this
{
id: 1,
device_mrid: "xxx1",
canaryDeviceId: "xxx",
},
{
id: 2,
device_mrid: "xxx2",
canaryDeviceId: "xxx",
},
{
id: 3,
device_mrid: "xxx3",
canaryDeviceId: "xxx",
},
I was able to create a dataGrid table using fake API and the want to get the end result like this https://codesandbox.io/s/bold-leakey-eu3cq?file=/src/App.js
I use the redux state metersList.metersData.data to save meters data.
My code is Looking like this:
import React, { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { readWaterMeter } from "./components/actions/waterActions";
import { FormattedMessage } from "react-intl";
import { DataGrid } from "@material-ui/data-grid";
export default function WaterNew() {
const dispatch = useDispatch();
const metersList = useSelector((state) => state.waterReducer);
useEffect(() => {
dispatch(readWaterMeter());
}, [dispatch]);
let rows = [];
rows =
metersList.metersData.data &&
metersList.metersData.data.length > 0
? metersList.metersData.data.map((obj, index) => {
return (rows = {
id: index,
device_mrid: obj.device_mrid,
canaryDeviceId: obj.canaryDeviceId
});
})
: " ";
const columns = [
{
field: "device_mrid",
headerName: "device_mrid",
flex: 1,
renderCell: ({ value }) => <FormattedMessage id={value} />
},
{
field: "canaryDeviceId",
headerName: "canaryDeviceId",
flex: 1,
renderCell: ({ value }) => <FormattedMessage id={value} />
}
];
return (
<div className="App" style={{ height: "100%", width: "100%" }}>
<DataGrid rows={rows} columns={columns} />
{console.log("metersList", metersList.metersData.data)}
</div>
);
}
I am able to see my meters data in console.log(return) but not able to map.
Initially I got this error:
Uncaught (in promise) TypeError: Cannot read property 'length' of undefined
After that I have added length property then I am getting another error like this
Uncaught (in promise) TypeError: e.forEach is not a function
Now I don't know how to proceed....
And the second issue is I am repeating the renderCell option in Columns, is there any better way to write the renderCell to reduce the lines of code?
I really appreciate the help.
Upvotes: 0
Views: 4416
Reputation:
I have similar error "TypeError: Cannot read property 'length' of undefined", but with React Query as data source. Solved it by checking data state, if it "isLoading" - display empty array.
const { isLoading, error, data } = useQuery([apiUrl], () =>
fetch(apiUrl).then((res) => res.json())
);
<DataGrid
rows={!isLoading ? data : []}
columns={columns}
pageSize={100}
rowsPerPageOptions={[50]}
checkboxSelection
disableSelectionOnClick
experimentalFeatures={{ newEditingApi: true }}
components={{ Toolbar: GridToolbar }}
/>;
Upvotes: 0
Reputation: 237
After adding an empty array to the useSelector, it worked and also I removed length method and ternary operator from rows.
const metersList = useSelector(
(state) => state.waterReducer.metersData.data || []
);
let rows = [];
rows = metersList.map((obj, index) => {
return (rows = {
id: index,
device_mrid: obj.device_mrid,
canaryDeviceId: obj.canaryDeviceId,
});
});
Upvotes: 1