Topic: Having trouble using api with datatable
import React, { Component } from 'react'; import { MDBDataTable, Row, Col, Card, CardBody } from 'mdbreact'; import axios from 'axios'; const url = 'http://jsonplaceholder.typicode.com/posts'; class TableSectionInbound extends Component { constructor(props) { super(props); this.state= { posts: [], isLoading:true, tableRows: [], }; } componentWillMount=async() => { await axios.get(url) .then(response => response.data) .then(data => { // console.log(data); // if (err) throw err; this.setState({ posts: data }) }) .then(async() => { this.setState({ tableRows:this.assemblePosts(), isLoading:false }) console.log(this.state.tableRows); }); } assemblePosts= () => { let posts =this.state.posts.map((post) => { return ( { number: post.id, title: post.title, user: post.userId, body: post.body, } ) }); return posts; } render() { const data = { columns: [ { label:'#', field:'number', }, { label:'Title', field:'title', }, { label:'User ID', field:'user', }, { label:'Body', field:'body', }, ], rows:this.state.tableRows, } return ( <RowclassName="mb-4"> <Col md="12"> <Card> <CardBody> <MDBDataTable striped bordered hover data={data} /> </CardBody> </Card> </Col> </Row> ) } } export default TableSectionInbound;
Jakub Mandra staff premium answered 6 years ago
robnewton pro commented 6 years ago
That did the thing. It works now. Thank you for all your help.
Jakub Mandra staff premium commented 6 years ago
I'm glad i could help, shame that took so long :)
Jakub Mandra staff premium answered 6 years ago
Ok, what kind of data do you provide form your redux store?
To use search, component needs to filter out what you are searching for (String value). We implemented toString() method on ech row key.
So app wont break with data like this:
rows: [
{
id: 12,
name: 'name',
category: 'category',
average: 'average',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
userId: 'userId'
},
{
id: 1,
name: 'john',
category: 'category',
average: 'average',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
userId: 'userId'
}
]
Maybe you have empty keys inside row's objects?
When I used this object my app has broken:
rows: [
{
id: 12,
name: 'name',
category: 'category',
average: 'average',
createdAt: undefined,
updatedAt: 'updatedAt',
userId: 'userId'
},
Jakub Mandra staff premium answered 6 years ago
robnewton pro commented 6 years ago
Thank you for the response. I have now changed componentWillMount to componentDidMount and removed all the async functions and awaits. I'm still having the same problem though. I'm still getting the logged version of what I want, but the rows still don't show. I do know about the API data source, but the API I am using has a different format. The way I'm doing it is pretty much just reformatting it for use with the data variable though.
Jakub Mandra staff premium answered 6 years ago
<button onClick={this.buildRows}>Assemble</button>
buildRows = () => this.setState({ tableRows: this.assemblePosts() });
robnewton pro commented 6 years ago
Correct, the table structure appears with all the correct column names, but no rows appear. I just tested your experiment, added multiple console.log()'s in to make sure it was working correctly, and while the button and setting of the state work, nothing is being posted to the table still. While waiting for a response I have tested a few other things too. I tried using the forEach() method and instead of setting the rows object to to this.state.tableRows, I made it an empty array that I am using .push() to push the data to it. It's pretty much the same concept, and it also doesn't work. If this ends up not working and I switch to a basic table, would it be possible to add pagination and a search bar to it? If so, how would I go about doing that?
Jakub Mandra staff premium commented 6 years ago
There is complex logic behind those functionalities, that is why we built dedicated component.
sedonawebservices pro answered 6 years ago
My Datatable works great, except when I click in the search bar, the component breaks. Is there a recommended implementation for lifecycles?
import React, {Component} from "react";
import { DataTable, Container, Row, Col, Card, CardBody } from "mdbreact";
import {connect} from 'react-redux'
import {topics} from '../store'
class TopicsPage extends Component {
constructor(props) {
super(props)
}
componentDidMount() {
this.props.fetchTopics()
}
render() {
const {topics} = this.props
const data = {
columns: [
{
label: "Id",
field: "id",
sort: "asc",
width: 150
}, {
label: "Name",
field: "name",
sort: "asc",
width: 150
},
{
label: "Category",
field: "category",
sort: "asc",
width: 270
},
{
label: "Average",
field: "average",
sort: "asc",
width: 270
},
{
label: "createdAt",
field: "createdAt",
sort: "asc",
width: 270
},
{
label: "updatedAt",
field: "updatedAt",
sort: "asc",
width: 270
},
{
label: "userId",
field: "userId",
sort: "asc",
width: 270
}
],
rows: topics
}
return (
<Container className="mt-3">
<Row className="py-3">
<Col md="12">
<Card>
<CardBody>
<DataTable striped bordered hover data={data} />
</CardBody>
</Card>
</Col>
</Row>
</Container>
)
}
}
const mapProps = state => {
return {
topics: state.topics
}
}
const mapDispatch = dispatch => ({
fetchTopics() { dispatch(topics()) }
})
export default connect(mapProps, mapDispatch)(TopicsPage)
Jakub Mandra staff premium commented 6 years ago
Your code looks properly.
Can you provide error msg?
Does that error occur already after clicking or writing?
sedonawebservices pro commented 6 years ago
Hi. The error happens only after typing. Right away, I get a blank white screen.
sedonawebservices pro answered 6 years ago
Regarding previous comment, here is an error message I see in Javascript console, when I start to type in Search bar:
mdbreact.js:8117 Uncaught TypeError: Cannot read property 'toString' of null
at mdbreact.js:8117
at Array.filter (<anonymous>)
at t.<anonymous> (mdbreact.js:8115)
at getStateFromUpdate (react-dom.development.js:11427)
at processUpdateQueue (react-dom.development.js:11488)
at updateClassInstance (react-dom.development.js:13270)
at updateClassComponent (react-dom.development.js:14860)
at beginWork (react-dom.development.js:15716)
at performUnitOfWork (react-dom.development.js:18750)
at workLoop (react-dom.development.js:18791)
at HTMLUnknownElement.callCallback (react-dom.development.js:147)
at Object.invokeGuardedCallbackDev (react-dom.development.js:196)
at invokeGuardedCallback (react-dom.development.js:250)
at replayUnitOfWork (react-dom.development.js:17998)
at renderRoot (react-dom.development.js:18909)
at performWorkOnRoot (react-dom.development.js:19812)
at performWork (react-dom.development.js:19722)
at flushInteractiveUpdates$1 (react-dom.development.js:19992)
at batchedUpdates (react-dom.development.js:2259)
at dispatchEvent (react-dom.development.js:5105)
at interactiveUpdates$1 (react-dom.development.js:19978)
at interactiveUpdates (react-dom.development.js:2267)
at dispatchInteractiveEvent (react-dom.development.js:5081)
(anonymous) @ mdbreact.js:8117
(anonymous) @ mdbreact.js:8115
getStateFromUpdate @ react-dom.development.js:11427
processUpdateQueue @ react-dom.development.js:11488
updateClassInstance @ react-dom.development.js:13270
updateClassComponent @ react-dom.development.js:14860
beginWork @ react-dom.development.js:15716
performUnitOfWork @ react-dom.development.js:18750
workLoop @ react-dom.development.js:18791
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
replayUnitOfWork @ react-dom.development.js:17998
renderRoot @ react-dom.development.js:18909
performWorkOnRoot @ react-dom.development.js:19812
performWork @ react-dom.development.js:19722
flushInteractiveUpdates$1 @ react-dom.development.js:19992
batchedUpdates @ react-dom.development.js:2259
dispatchEvent @ react-dom.development.js:5105
interactiveUpdates$1 @ react-dom.development.js:19978
interactiveUpdates @ react-dom.development.js:2267
dispatchInteractiveEvent @ react-dom.development.js:5081
index.js:1452 The above error occurred in the <t> component:
in t (at DatabasePage.js:60)
in div (created by t)
in t (at DatabasePage.js:59)
in div (created by t)
in t (at DatabasePage.js:58)
in div (created by t)
in t (at DatabasePage.js:57)
in div (created by t)
in t (at DatabasePage.js:56)
in div (created by t)
in t (at DatabasePage.js:55)
in DatabasePage (created by Connect(DatabasePage))
in Connect(DatabasePage) (created by Route)
in Route (at Routes.js:137)
in Switch (at Routes.js:135)
in div (at Routes.js:57)
in Router (at Routes.js:56)
in Routes (created by Connect(Routes))
in Connect(Routes) (at App.js:38)
in main (at App.js:37)
in div (at App.js:35)
in App (created by Connect(App))
in Connect(App) (at src/index.js:15)
in Provider (at src/index.js:14)
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://fb.me/react-error-boundaries to learn more about error boundaries.
function.console.(anonymous function) @ index.js:1452
logCapturedError @ react-dom.development.js:16489
logError @ react-dom.development.js:16524
update.callback @ react-dom.development.js:17499
callCallback @ react-dom.development.js:11592
commitUpdateEffects @ react-dom.development.js:11632
commitUpdateQueue @ react-dom.development.js:11622
commitLifeCycles @ react-dom.development.js:16779
commitAllLifeCycles @ react-dom.development.js:18160
callCallback @ react-dom.development.js:147
invokeGuardedCallbackDev @ react-dom.development.js:196
invokeGuardedCallback @ react-dom.development.js:250
commitRoot @ react-dom.development.js:18365
completeRoot @ react-dom.development.js:19894
performWorkOnRoot @ react-dom.development.js:19817
performWork @ react-dom.development.js:19722
flushInteractiveUpdates$1 @ react-dom.development.js:19992
batchedUpdates @ react-dom.development.js:2259
dispatchEvent @ react-dom.development.js:5105
interactiveUpdates$1 @ react-dom.development.js:19978
interactiveUpdates @ react-dom.development.js:2267
dispatchInteractiveEvent @ react-dom.development.js:5081
mdbreact.js:8117 Uncaught TypeError: Cannot read property 'toString' of null
at mdbreact.js:8117
at Array.filter (<anonymous>)
at t.<anonymous> (mdbreact.js:8115)
at getStateFromUpdate (react-dom.development.js:11427)
at processUpdateQueue (react-dom.development.js:11488)
at updateClassInstance (react-dom.development.js:13270)
at updateClassComponent (react-dom.development.js:14860)
at beginWork (react-dom.development.js:15716)
at performUnitOfWork (react-dom.development.js:18750)
at workLoop (react-dom.development.js:18791)
at renderRoot (react-dom.development.js:18876)
at performWorkOnRoot (react-dom.development.js:19812)
at performWork (react-dom.development.js:19722)
at flushInteractiveUpdates$1 (react-dom.development.js:19992)
at batchedUpdates (react-dom.development.js:2259)
at dispatchEvent (react-dom.development.js:5105)
at interactiveUpdates$1 (react-dom.development.js:19978)
at interactiveUpdates (react-dom.development.js:2267)
at dispatchInteractiveEvent (react-dom.development.js:5081)
(anonymous) @ mdbreact.js:8117
(anonymous) @ mdbreact.js:8115
getStateFromUpdate @ react-dom.development.js:11427
processUpdateQueue @ react-dom.development.js:11488
updateClassInstance @ react-dom.development.js:13270
updateClassComponent @ react-dom.development.js:14860
beginWork @ react-dom.development.js:15716
performUnitOfWork @ react-dom.development.js:18750
workLoop @ react-dom.development.js:18791
renderRoot @ react-dom.development.js:18876
performWorkOnRoot @ react-dom.development.js:19812
performWork @ react-dom.development.js:19722
flushInteractiveUpdates$1 @ react-dom.development.js:19992
batchedUpdates @ react-dom.development.js:2259
dispatchEvent @ react-dom.development.js:5105
interactiveUpdates$1 @ react-dom.development.js:19978
interactiveUpdates @ react-dom.development.js:2267
dispatchInteractiveEvent @ react-dom.development.js:5081
sedonawebservices pro answered 6 years ago
Yes Jakub, some of my data is "null". So I will try replacing the null values with an empty string.
sedonawebservices pro answered 6 years ago
Thanks, that fixed it. I adjusted the database models so that any null values are retrieved as blank strings.
Jakub Mandra staff premium commented 6 years ago
Glad I could help.
We will add this 'restriction' to the documentation.
Looks like my comment has been deleted Oo
valentineEzeh answered 6 years ago
Hello I am Having the same issue. When I try to input in the search form I get the same toString error. Here is my code below:
import React from "react";
import { MDBDataTable } from 'mdbreact';
import datetime from 'node-datetime';
class TransactionList extends React.Component {
render() {
const transactions = this.props.allTransactions;
const data = {
columns: [
{
label: 'Agent Name',
field: 'agentName',
sort: 'asc',
width: 150
},
{
label: 'Driver Name',
field: 'driverName',
sort: 'asc',
width: 150
},
{
label: 'Agent Phone Number',
field: 'agentNumber',
sort: 'asc',
width: 150
},
{
label: 'Vehicle Number',
field: 'vehicleNumber',
sort: 'asc',
width: 150
},
{
label: 'Date',
field: 'date',
sort: 'asc',
width: 150
},
{
label: 'Time',
field: 'time',
sort: 'asc',
width: 150
},
],
rows: transactions.map(transaction => {
return {
agentName: transaction.agentName,
driverName: transaction.driverName,
agentNumber: `${0}${transaction.agentNumber}`,
vehicleNumber: transaction.vehicleNumber,
date: datetime.create(transaction.date).format('m/d/y'),
time: datetime.create(transaction.date).format('H:M:S')
}
})
}
return (
<div class="col-md-9">
<div class="panel panel-default my-auto" id="transaction">
<div class="panel-heading main-color-bg">
<h3 class="panel-title">All Transactions</h3>
</div>
<div className="panel-body">
<MDBDataTable
striped
bordered
small
data={data}
/>
</div>
</div>
</div>
);
}
}
export default TransactionList;
Jakub Mandra staff premium answered 6 years ago
Hey @valentineEzeh,
To use search, the component needs to filter out what you are searching for (String value). We implemented toString() method on each row key.
So the app won't break with data like this (numbers allowed):
rows: [
{
id: 12,
name: 'name',
category: 'category',
average: 'average',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
userId: 'userId'
},
{
id: 1,
name: 'john',
category: 'category',
average: 'average',
createdAt: 'createdAt',
updatedAt: 'updatedAt',
userId: 'userId'
}
]
Maybe you have empty keys inside row's objects?
Check this example, because createdAt: undefined
the app brokes when search is used:
rows: [
{
id: 12,
name: 'name',
category: 'category',
average: 'average',
createdAt: undefined,
updatedAt: 'updatedAt',
userId: 'userId'
},
Best,
Jakub
Group answered 6 years ago
How to implement click event on data table row const row = [
{
sl: 'Tiger Nixon',
emp_name: 'System Architect',
movementType: 'Edinburgh',
applicationDate: '61',
fromDate: '2011/04/25',
toDate: '$320',
reason: '$320',
address: '$320',
status: "completed",
clickEvent: handleRowClick
},
]
Jakub Mandra staff premium answered 6 years ago
Hi,
The simples example could be:
import React from 'react';
import { MDBDataTable } from 'mdbreact';
class DatatablePage extends React.Component {
state = {
data: {
columns: [
{
label: 'Name',
field: 'name',
sort: 'asc',
width: 150
},
{
label: 'Position',
field: 'position',
sort: 'asc',
width: 270
},
{
label: 'Office',
field: 'office',
sort: 'asc',
width: 200
},
{
label: 'Age',
field: 'age',
sort: 'asc',
width: 100
},
{
label: 'Start date',
field: 'date',
sort: 'asc',
width: 150
},
{
label: 'Salary',
field: 'salary',
sort: 'asc',
width: 100
}
],
rows: [
{
name: 'Tiger Nixon',
position: 'System Architect',
office: 'Edinburgh',
age: '61',
date: '2011/04/25',
salary: '$320',
clickEvent: e => this.handleClick(e, 'Tiger Nixon')
},
{
name: 'Garrett Winters',
position: 'Accountant',
office: 'Tokyo',
age: '63',
date: '2011/07/25',
salary: '$170',
clickEvent: e => this.handleClick(e, 'Garret Winters')
}
]
}
}
handleClick = (e, data) => {
console.log('event target:', e.target, 'data:', data);
}
render() {
return (
<MDBDataTable
striped
bordered
hover
data={this.state.data}
/>
);
}
}
export default DatatablePage;
Best,
Jakub
Simic answered 4 years ago
Hello, How can i connect Datatable pagination with API calls. For example, I want first get 10 items from API and show them, then get second 10 intem from APi etc. Best, Selena
Piotr Glejzer staff commented 4 years ago
you probably need to fetch your data from API and use asynchronous mechanism of js to do that like async/await with settimeout and update prop.
Shantanu Singh answered 4 years ago
how to make my search box work to search in datatble(api)??
Piotr Glejzer staff commented 4 years ago
what do you mean by my search box? Are you using a custom search box?
FREE CONSULTATION
Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.
Answered
- User: Pro
- Premium support: No
- Technology: MDB React
- MDB Version: 4.7.0
- Device: MacBook Pro
- Browser: Google Chrome
- OS: macOS High Sierra 10.13.2
- Provided sample code: No
- Provided link: No