5

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}
    />
);
}
2
  • 2
    Call getShotjes() in a useEffect hook, and instead of returning the data, use setData(data) to set it (separate columns and data in your state). Commented May 18, 2020 at 11:18
  • Thanks, I'll try that Commented May 18, 2020 at 11:42

1 Answer 1

1

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)

        }}
    />

);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.