Reputation: 129
I'm building a small react app using firebase for both hosting and storing data, I am using a Material-Table for showing the data. The problem is i get this error when I'm trying to load the data into the table:
Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead. in EditTable (at App.js:12) in div (at App.js:10) in App (at src/index.js:10) in StrictMode (at src/index.js:9)
This is the code for the table:
import React from 'react';
import MaterialTable from 'material-table';
import { forwardRef } from 'react';
import AddBox from '@material-ui/icons/AddBox';
import ArrowDownward from '@material-ui/icons/ArrowDownward';
import Check from '@material-ui/icons/Check';
import ChevronLeft from '@material-ui/icons/ChevronLeft';
import ChevronRight from '@material-ui/icons/ChevronRight';
import Clear from '@material-ui/icons/Clear';
import DeleteOutline from '@material-ui/icons/DeleteOutline';
import Edit from '@material-ui/icons/Edit';
import FilterList from '@material-ui/icons/FilterList';
import FirstPage from '@material-ui/icons/FirstPage';
import LastPage from '@material-ui/icons/LastPage';
import Remove from '@material-ui/icons/Remove';
import SaveAlt from '@material-ui/icons/SaveAlt';
import Search from '@material-ui/icons/Search';
import ViewColumn from '@material-ui/icons/ViewColumn';
import {getShotjes} from './shotjesDao'
const tableIcons = {
Add: forwardRef((props, ref) => <AddBox {...props} ref={ref} />),
Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Delete: forwardRef((props, ref) => <DeleteOutline {...props} ref={ref} />),
DetailPanel: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
Export: forwardRef((props, ref) => <SaveAlt {...props} ref={ref} />),
Filter: forwardRef((props, ref) => <FilterList {...props} ref={ref} />),
FirstPage: forwardRef((props, ref) => <FirstPage {...props} ref={ref} />),
LastPage: forwardRef((props, ref) => <LastPage {...props} ref={ref} />),
NextPage: forwardRef((props, ref) => <ChevronRight {...props} ref={ref} />),
PreviousPage: forwardRef((props, ref) => <ChevronLeft {...props} ref={ref} />),
ResetSearch: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Search: forwardRef((props, ref) => <Search {...props} ref={ref} />),
SortArrow: forwardRef((props, ref) => <ArrowDownward {...props} ref={ref} />),
ThirdStateCheck: forwardRef((props, ref) => <Remove {...props} ref={ref} />),
ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};
export default async function EditTable() {
const [state, setState] = React.useState({
columns: [
{ title: 'ID', field: 'ID' , type: 'numeric' },
{ title: 'uitdeler', field: 'Uitdeler' },
{ title: 'ontvanger', field: 'Ontvanger' },
{ title: 'Uitgedeeld', field: 'Uitgedeeld', lookup: { 1: true, 0: false },},
{ title: 'datum', field: 'Datum',
},
],
data: getShotjes(),
});
return (
<MaterialTable
title="Editable Example"
columns={state.columns}
data={this.state.data}
icons={tableIcons}
/>
);
And here is my simple dao file minus the the config:
import firebase from 'firebase/app'
export async function getShotjes() {
try {
require("firebase/firestore");
const firebaseConfig = {
};
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
var db = firebase.firestore();
const snapshot = await db.collection('shotjes').get();
return snapshot.docs.map(doc => doc.data());
}
catch (e) {
console.log(e);
}
}
EDIT:
So adding a useEffect hook and splitting the data and the columns states worked to remove all the errors. though i still don't see any data appear in the table. My Table component now looks like this:
export default function EditTable() {
var [state, setState] = React.useState({
columns: [
{ title: 'ID', field: 'id' , type: 'numeric' },
{ title: 'Uitdeler', field: 'uitdeler' },
{ title: 'Ontvanger', field: 'ontvanger' },
{ title: 'Uitgedeeld', field: 'uitgedeeld', lookup: { 1: true, 0: false },},
{ title: 'Datum', field: 'datum',
},
],
});
var [data, setData] = React.useState([]);
console.log(JSON.stringify(data));
useEffect(() => {
(async () => {
const result = await getShotjes();
console.log(result);
setData(result);
})();
}, []);
return (
<MaterialTable
title="Editable Example"
columns={state.columns}
data={data.data}
icons={tableIcons}
/>
);
}
Upvotes: 5
Views: 7395
Reputation: 129
This is how i fixed it, I also added functionality for adding an removing data.
EditTable.js:
export default function EditTable() {
var [state, setState] = React.useState({
columns: [
{ title: 'ID', field: 'id', type: 'numeric', editable: false},
{ title: 'Uitdeler', field: 'uitdeler' },
{ title: 'Ontvanger', field: 'ontvanger' },
{ title: 'Datum', field: 'datum', type: 'date'},
],
});
var [data, setData] = React.useState([]);
const [isLoading,setIsLoading] = useState(false);
useEffect(() => {
// By moving this function inside the effect, we can clearly see the values it uses.
setIsLoading(true);
async function fetchProduct() {
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
setData(await getShotjes());
setIsLoading(false);
}
fetchProduct();
}, []);
const handleCreateShotje = async (shotje) => {
setIsLoading(true);
await addShotje(shotje).then(async () => {
setData(await getShotjes());
});
setIsLoading(false);
};
const handleDeleteShotje = async (id) => {
setIsLoading(true);
await removeShotje(id).then(async () => {
setIsLoading(true);
setTimeout(async function () {{
setData(await getShotjes());
}
}, 400);
setIsLoading(false);
});
};
return (
<MaterialTable
title="Shotjes"
columns={state.columns}
data={(data)}
icons={tableIcons}
isLoading={isLoading}
editable={{
isEditable: rowData => rowData.name === "id", // make id not editable
onRowAdd: (newData) => handleCreateShotje(newData),
onRowDelete: (oldData) => handleDeleteShotje(oldData.id)
}}
/>
);
}
Upvotes: 1