Search code examples
reactjsreact-hooksmaterial-uidatagridstate

How to grab data from selected row in React MUI Data-Grid table with Axios


I am trying to use the example here to add the selectedRow functionality from @mui/x-data-grid to return all the data form a selected row. In the demo, they are using the useDemoData mod to populate the table, whereas I am using Axios to make a call to my API to populate the rows and using preconfigured columns.

import React, { useState, useEffect } from 'react';
import axios from "axios";
import { DataGrid, GridToolbar } from '@mui/x-data-grid';

const columns = [
    { field: 'id', headerName: 'Job ID', width: 170 },
    { field: 'file_name', headerName: 'File Name', width: 250 },
    { field: 'product_type', headerName: 'Product Type', width: 300 },    
    { field: 'status', headerName: 'Status', width: 170, editable: true },
];  

function QueueMgrTable() {
    const [data, setData] = useState([]);
    const [loadingData, setLoadingData] = useState(true);
    const [selectedRows, setSelectedRows] = useState([]);

    async function getData() {
        await axios
            .get('https://myendpoint.com/test/jobs', {
            headers: {
                'Content-Type': 'application/json'
            }
            })
            .then((response) =>{
                var test_data = response.data.data;
                setData(
                    test_data.map((x) => {
                        return {
                            id: parseInt(`${x.job_id}`),
                            file_name: `${x.file_name}`,
                            product_type: `${x.product_type}`,
                            status: `${x.status}`
                        }
                    })
                );
                setLoadingData(false);
            });
    }  
     
    useEffect((data) => {
        console.log(config);
        getData();
        if (loadingData) {
            getData();
        }
    }, []);

    return (
        <div style={{ height: 600, width: '100%' }}>
            {loadingData ? (
                <p>Loading. Please wait...</p>
        ) : (    
            <DataGrid
            columns={columns}
            pageSize={20}
            rowsPerPageOptions={[10]}
            checkboxSelection
            components={{ Toolbar: GridToolbar }}
            onSelectionModelChange={(ids) => {
                const selectedIDs = new Set(ids);
                const selectedRows = data.rows.filter((row) =>
                    selectedIDs.has(row.id),
            );
            setSelectedRows(selectedRows);
            }}
            rows={data}
            />
        )}
    
        <pre style={{ fontSize: 10 }}>
            {JSON.stringify(selectedRows, null, 4)}
        </pre>
        </div>
    );
};

export default QueueMgrTable;

When I click on a row in the above, I get the following error. Any suggestions or clues as to what I am doing wrong here? I suspect that it trying to use filter when the data is undefined for some reason due to state. enter image description here


Solution

  • To resolve this issue, I had to make a few simple changes to the following block of code. First, I changed const to let. Then I had to remove the rows from data.rows.filter((row) ... as it was undefined. The data object is already defined as an array, and therefore, I can use the filter method to find the correct "row" data based on the id.

    onSelectionModelChange={(ids) => {
        let selectedIDs = new Set(ids);
        let selectedRows = data.filter((row) =>
            selectedIDs.has(row.id),
        );
        setSelectedRows(selectedRows);
    }}
    

    This resolved the error issue and allowed me to properly define selectedIDs.