Search code examples
node.jsreactjsjsondatagridreact-table

React - fill datagrid with json fetch from node backend - TypeError null is not an object


I try to fill a React DataGrid with data from a JSON provided by node backend.

The backend code looks as follows:

app.get("/articles", (req, res) => {
res.json([
    {
        "title":"Test Article One",
        "timestamp":"09-01-2023",
        "text":"Test text one"
    },
    {
        "title":"Test Article Two",
        "timestamp":"10-01-2023",
        "text":"Test text two"
    },
    {
        "title":"Test Article Three",
        "timestamp":"11-01-2023",
        "text":"Test text three"
    }])
})

The React code looks as follows:

const MemberPage = () => {
    const [articles, setArticles] = useState([])
    const [articleKeys, setArticleKeys] = useState([])

    useEffect(() => {
        fetch("http://localhost:3001/articles")
        .then((res) => res.json())
        .then((data) => {
            setArticles(data)
            setArticleKeys(Object.keys(data[0]))
        })
    })

    return (
        <div id="memberpage-main-container">
            <DataGrid columns={articleKeys} rows={articles} />
        </div>
    )
}

I get the error message TypeError: null is not an object (evaluating 'measuringCell.getBoundingClientRect') in the browser console and the page wouldn't render. I first thought, it is because the DataGrid is rendered before the useEffect fetches the data which I've red in other answers, however, when I write:

const articleKeys = []

const articles = []

it works (I'm mean, it's an empty page then, but I don't get any errors). So, I would expect it not to be a problem when setting useState([]).

Any help is appreciated.


Solution

  • So, I've found a solution by switching from react-data-grid to @mui/x-data-grid.

    The code now looks as follows:

    import React, { useState, useEffect } from "react"
    import { DataGrid } from "@mui/x-data-grid"
    
    const MemberPage = () => {
    
        const [articles, setArticles] = useState([])
        const [articleKeys, setArticleKeys] = useState([])
    
        function parseArticleKeys(keys) {
            let tableColumns = []
            for (let i = 0; i < keys.length; i++) {
                tableColumns.push({field: keys[i], headerName: keys[i], width: 300})
            }
            return tableColumns
        }
    
        useEffect(() => {
            fetch("http://localhost:3001/articles")
            .then((res) => res.json())
            .then((data) => {
                setArticles(data)
                setArticleKeys(Object.keys(data[0]))
            })
        })
    
        return ( 
            <div id="memberpage-news-container">
                <DataGrid columns={parseArticleKeys(articleKeys)} rows={articles} />
            </div>
        )
    }
    
    export default MemberPage
    

    I tried a similar thing with react-data-grid but couldn't get it to work. If someone has an idea to accomplish that with react-data-grid, it still might be helpful for others but I personally am ok with that solution.