2

I have a question in terms of how data is updated in the DataGrid component from the @mui/x-data-grid module in React if anyone has experience with that Material UI library for displaying data in a table. The issue that I am having is in reference to updating the data in the table when an API fetch is completed. I am using react-query to fetch data from an API and am hoping to populate the table with this data. However, even after the fetch is complete, I still get the No rows message as you can see below in the table.

enter image description here

This does not make sense to me. As you can see in my console below, the data is fetching properly after the loading phase is completed in react-query. I am refetching the data every 1000 milliseconds just to emphasize the fact that this data is returning properly from the API. As you can see, an array of 3 objects is returning from the API to the Client as I would expect:

enter image description here

Here is the code process that I am going through:

First I created a hook with react-query to fetch this data from the API

export default function useFetchArtistSongs() {
    const { artist } = useUserData();
    const { _id } = artist;
    return useQuery(['fetchArtistSongs'], async () => {
        const artistSongsResponse = await axios({
            method: 'GET',
            url: `http://localhost:2000/api/get-artist-audio/${_id}`,
        }).then(response => {
            return response.data;
        });
        return artistSongsResponse;
    },  {
            refetchInterval: 3600000,
        },
    );
}

Next, I created a dataLayer within the component that renders the table so that I can pass the data property (list of objects) to the display layer that displays the table:

function useDataLayer() {
    const { data: artistSongs = [], isLoading } = useFetchArtistSongs();

    return {
        artistSongs,
        isLoading,
    };
}

I give the array of objects a default value to avoid an undefined error and I also get the isLoading property from the useQuery hook.

I finally pass the data to my component and then to the table:

function ClipsTableTest_DisplayLayer({
    artistSongs,
    isLoading,
}: ClipsTableDisplayLayerProps) {
    console.log(artistSongs);
    return (
        <ClipsTableContainer>
            <DataGrid 
                columns={columns}
                getRowId={(row: any) => row._id}
                loading={isLoading}
                rows={artistSongs}
                rowHeight={100}
                autoHeight
                autoPageSize
                disableColumnSelector
                disableRowSelectionOnClick
                hideFooterSelectedRowCount
            />
        </ClipsTableContainer>
    );
}

When I log the artistSongs array to the console it continuously updates and logs the data if I set the refetch rate to 1000 milliseconds. The catch in react-query is also updated. The table seems to be the only thing not getting the updated data.

I attempted to use a useEffect hook in order to set a state variable as the data updates and pass a state variable to the rows property of the DataGrid, but that failed too. I also tried useMemo with the same result. I even just straight up abandoned good programming structure and called fetched the data with axios directly in the display layer of this component -> updated the state variable once the response returned -> and the same No rows message appeared.

I am sorry if this was long-winded, but just wanted to be clear.

Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27
  • what happens if you pass the array as a variable (copy the array you're getting from the api ) without fetching it from api? – DuckDuckGoose Jul 21 '23 at 16:45
  • @DuckDuckGoose It works perfectly. When I just create a static array object in the code it appears without any issues, so this bug has to be directly related to the fetching process. – Simeon Ikudabo Jul 21 '23 at 16:46
  • can you show the columns array? – DuckDuckGoose Jul 21 '23 at 16:56
  • 1
    Please see https://stackoverflow.com/questions/76734800/mui-datagrid-with-issues-displaying-items-on-the-second-page-and-forward/76735734 – Pluto Jul 21 '23 at 17:43
  • Thanks @VictorL! That didn't work since the behavior here is different insofar as the data isn't even showing up on the first page. It's not an issue of pagination right now since no data is showing up at all. – Simeon Ikudabo Jul 21 '23 at 19:38
  • 1
    @SimeonIkudabo, You're welcome. Can you reproduce the problem in codesandbox? – Pluto Jul 21 '23 at 19:43

2 Answers2

1

The data isn't displayed because both the autoPageSize and autoHeight are set on the <DataGrid />. This issue occurs because the autoHeight scales the height according to the pageSize.

To fix these you can either remove the autoPageSize prop or remove the autoHeight prop and set the height explicitly, most likely in the <ClipsTableContainer />

gnerkus
  • 11,357
  • 6
  • 47
  • 71
  • 1
    Thanks for the help @gnerkus! Both of these are still set in my code now and it is working as expected. These do two different things based on the docs I've seen, so I have them both set for two different reasons (the amount of rows on the page for autoPageSize and then autoHeight to manipulate the size of the row). With both of them set, it is working as expected on both desktop and mobile devices right now. The issue appears to have been that the data was malformed and not that both properties were set, but will keep that in mind if it is an issue later on or in prod . Thanks! – Simeon Ikudabo Jul 23 '23 at 17:26
1

The issue here ended up being in the useFetchArtistSongs hook. When I return response.data this is just returning a tuple due to the way responses work in axios. I changed the return to:

return response.data.artistAudio;

instead of

return response.data;

and that resolved the problem.

Simeon Ikudabo
  • 2,152
  • 1
  • 10
  • 27