I am trying to create a table that uses an api to access data from a database.
import { COLUMNS } from './ActivityColumns.js'
import { getTable } from "./ApiCall.js"
export const SortingTable = () => {
const columns = useMemo(() => COLUMNS, [])
const [aaa, setData] = useState([])
const getData = () => {
getTable('activity').then(result => {
console.log('returning result')
return result;
})
}
const tableInstance = useTable({
columns: COLUMNS,
data: getData()
},
useSortBy)
}
The result in getData()
is the expected one, an array of Object dicts [ {..}, {..}, ..., {..}]
. The problem is that when tableInstance
tries to set the data
as the result of getData()
, I get the following error: useTable.js:591 Uncaught TypeError: Cannot read properties of undefined (reading 'forEach')
The exact line that causes the error is from useTable.js
:
data.forEach((originalRow, rowIndex) =>
accessRow(originalRow, rowIndex, 0, undefined, rows)
)
Before using an API I used a json file that has the same structure as the API’s response: [{..}, {..}, {..}]
. This one worked.
What goes wrong when trying to initiate with an API and how can I fix this error?
Edit 1: I tried to declare getData
inside the hook
export const SortingTable = () => {
const columns = useMemo(() => COLUMNS, [])
const getData = () => {
const [data, setData] = useState(null);
const getData = () => {
getTable('activity').then(result => {
console.log('returning result')
console.log(result)
setData(result);
})
}
getData();
return data;
}
const tableInstance = useTable({
columns: COLUMNS,
data: getData
},
useSortBy)
const { getTableProps, getTableBodyProps, headerGroups, footerGroups, rows, prepareRow } = tableInstance
}
2
Answers
Your
getData
function does not have a return. This means callinggetData()
would give youundefined
.Is
useTable
OK to work with an asynchronous function?If so, just return something from
getData
.If it expects its synchronous data you might need to put the results of
getData
into state so that it gets populated once available which in turn causes a rerender of your component and callinguseTable
again.The reason why your JSON was loaded without issue and your fetching is problematic is probably because you just imported/required the JSON which is synchronous while
getTable
obviously returns a thenable/Promise.getData
doesn’t return anything. So effectively you’re passinguseTable
an object{columns: COLUMNS, data: undefined}
.One way to fix this is to declare
getData
inside your hook, and use state to save the result of the API call: