Help me pls,
I have bind data to MaterialTable with remote feature without problems.
But now i want to be able to refresh this data with a trigger. I don't know if it is possible?
I know how to do it when data is an array. (with state)
but when data is a promise ....
Thks,
async fetchUsers(query){
let datas = await fetch("/datas")
return { data: datas, page: query.page, totalCount: datas.length}
}
refreshAllMyRemoteData(){
// here i want to be able to refresh the data but i don't know how to do it :)
}
...
<MaterialTable
data={this.fetchUsers}
detailPanel={[
{
icon: 'person_add_disabled',
render: rowData => {
return (<div onClick={this.refreshAllMyRemoteData}>click-me</div>)
},
}
]}
Hi @billBeOK ,
Your requirement makes sense. I resolved it with tableRef with new version 1.28.0
import { Grid, MuiThemeProvider } from '@material-ui/core';
import { createMuiTheme } from '@material-ui/core/styles';
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import MaterialTable from './material-table';
class App extends Component {
tableRef = React.createRef();
render() {
return (
<div style={{ maxWidth: '100%', direction }}>
<MaterialTable
tableRef={this.tableRef}
columns={[
{
title: 'Avatar',
field: 'avatar',
render: rowData => (
<img
style={{ height: 36, borderRadius: '50%' }}
src={rowData.avatar}
/>
),
},
{ title: 'Id', field: 'id' },
{ title: 'First Name', field: 'first_name' },
{ title: 'Last Name', field: 'last_name' },
]}
data={query =>
new Promise((resolve, reject) => {
let url = 'https://reqres.in/api/users?';
url += 'per_page=' + query.pageSize;
url += '&page=' + (query.page + 1);
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result.data,
page: result.page - 1,
totalCount: result.total,
})
});
})
}
title="Remote Data Example"
/>
<button
onClick={() => {
this.tableRef.current.onQueryChange();
}}
>
ok
</button>
</div>
);
}
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
module.hot.accept();
it's work like a charm !
Bravo
Help me please I am getting this this.tableRef.current.onQueryChange() undefined
I also had the error initially and then realized I missed tableRef = React.createRef(); right after class App extends Component {
Is there a way to change query before refreshing data?
In addition to having the search trigger on pressing the Enter key, I also added a "Clear" button with
clearSearchInput = () => {
// clear value
this.setState({
value: '',
})
// refresh table
this.tableRef.current.onQueryChange();
}
this.tableRef.current.onQueryChange();
the ref and this.tableRef.current.onQueryChange() saved my life bro! It works with functional component too using useRef!
this.tableRef.current.onQueryChange();the ref and this.tableRef.current.onQueryChange() saved my life bro! It works with functional component too using useRef!
Could you please share a functional component example?
this.tableRef.current.onQueryChange();the ref and this.tableRef.current.onQueryChange() saved my life bro! It works with functional component too using useRef!
Could you please share a functional component example?
using mbrn's previous code but with hooks:
import { Grid, MuiThemeProvider } from '@material-ui/core';
import { createMuiTheme } from '@material-ui/core/styles';
import React, { useRef } from 'react';
import ReactDOM from 'react-dom';
import MaterialTable from './material-table';
const App = () => {
tableRef = useRef();
return (
<div style={{ maxWidth: '100%', direction }}>
<MaterialTable
tableRef={tableRef}
columns={[
{
title: 'Avatar',
field: 'avatar',
render: rowData => (
<img
style={{ height: 36, borderRadius: '50%' }}
src={rowData.avatar}
/>
),
},
{ title: 'Id', field: 'id' },
{ title: 'First Name', field: 'first_name' },
{ title: 'Last Name', field: 'last_name' },
]}
data={query =>
new Promise((resolve, reject) => {
let url = 'https://reqres.in/api/users?';
url += 'per_page=' + query.pageSize;
url += '&page=' + (query.page + 1);
fetch(url)
.then(response => response.json())
.then(result => {
resolve({
data: result.data,
page: result.page - 1,
totalCount: result.total,
})
});
})
}
title="Remote Data Example"
/>
<button
onClick={() => tableRef.current.onQueryChange()}
>
ok
</button>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById('app')
);
A quick edit, but I think you get the point.
this.tableRef.current.onQueryChange();the ref and this.tableRef.current.onQueryChange() saved my life bro! It works with functional component too using useRef!
Could you please share a functional component example?
using mbrn's previous code but with hooks:
import { Grid, MuiThemeProvider } from '@material-ui/core'; import { createMuiTheme } from '@material-ui/core/styles'; import React, { useRef } from 'react'; import ReactDOM from 'react-dom'; import MaterialTable from './material-table'; const App = () => { tableRef = useRef(); return ( <div style={{ maxWidth: '100%', direction }}> <MaterialTable tableRef={tableRef} columns={[ { title: 'Avatar', field: 'avatar', render: rowData => ( <img style={{ height: 36, borderRadius: '50%' }} src={rowData.avatar} /> ), }, { title: 'Id', field: 'id' }, { title: 'First Name', field: 'first_name' }, { title: 'Last Name', field: 'last_name' }, ]} data={query => new Promise((resolve, reject) => { let url = 'https://reqres.in/api/users?'; url += 'per_page=' + query.pageSize; url += '&page=' + (query.page + 1); fetch(url) .then(response => response.json()) .then(result => { resolve({ data: result.data, page: result.page - 1, totalCount: result.total, }) }); }) } title="Remote Data Example" /> <button onClick={() => tableRef.current.onQueryChange()} > ok </button> </div> ); } ReactDOM.render( <App />, document.getElementById('app') );A quick edit, but I think you get the point.
When, I use the tableRef.current.OnQueryChange(), it throws an error saying _this.props.data is not a function.
Can Someone Help on it
Here's a screenshot

this.tableRef.current.onQueryChange();the ref and this.tableRef.current.onQueryChange() saved my life bro! It works with functional component too using useRef!
Could you please share a functional component example?
using mbrn's previous code but with hooks:
import { Grid, MuiThemeProvider } from '@material-ui/core'; import { createMuiTheme } from '@material-ui/core/styles'; import React, { useRef } from 'react'; import ReactDOM from 'react-dom'; import MaterialTable from './material-table'; const App = () => { tableRef = useRef(); return ( <div style={{ maxWidth: '100%', direction }}> <MaterialTable tableRef={tableRef} columns={[ { title: 'Avatar', field: 'avatar', render: rowData => ( <img style={{ height: 36, borderRadius: '50%' }} src={rowData.avatar} /> ), }, { title: 'Id', field: 'id' }, { title: 'First Name', field: 'first_name' }, { title: 'Last Name', field: 'last_name' }, ]} data={query => new Promise((resolve, reject) => { let url = 'https://reqres.in/api/users?'; url += 'per_page=' + query.pageSize; url += '&page=' + (query.page + 1); fetch(url) .then(response => response.json()) .then(result => { resolve({ data: result.data, page: result.page - 1, totalCount: result.total, }) }); }) } title="Remote Data Example" /> <button onClick={() => tableRef.current.onQueryChange()} > ok </button> </div> ); } ReactDOM.render( <App />, document.getElementById('app') );A quick edit, but I think you get the point.
When, I use the tableRef.current.OnQueryChange(), it throws an error saying _this.props.data is not a function.
Can Someone Help on it
Here's a screenshot
Post your code?
Sry, I forgot in hurry
const colHeads = columns.map((cl)=>{
return cl==='kills'||cl==='rank'||cl==='wallet'
? {title:colValues[cl],field:cl,type:'numeric',editable: 'onUpdate'}
: {title:colValues[cl],field:cl,editable: 'never'}
});
const colData = players && players.map((pl,ind)=>{
let cp={}
columns && columns.map((cl,cind)=>{
return cl==='srno'? cp[cl]=players.indexOf(pl)+1 : cp[cl]=pl[cl]
})
return cp;
})
const tRef = React.useRef();
const editF = {
onRowAdd:null,
onRowUpdate:(newData,oldData)=>
new Promise((resolve,reject)=>{
setTimeout(()=>{
let data = colData;
console.log(state)
let inx = data.indexOf(oldData);
newData['kills']=parseInt(newData['kills'])
newData['wallet']=parseInt(newData['wallet'])
newData['rank']=parseInt(newData['rank'])
data[inx] = newData;
resolve();
},1000)
}),
onRowDelete : null
};
const tRF = ()=>{
setState(state)
}
return(
<React.Fragment>
<div>
<MaterialTable
tableRef={tRef}
title="Players"
columns={colHeads}
data={colData}
editable={isEditing? editF : null}
/>
<button
onClick={() => {
tRef.current.onQueryChange();
}}
>
ok
</button>
<div hidden={!bttnname}>
<button onClick={()=>tRF()} className='waves-effect waves-light btn hoverable'>{bttnname}</button>
</div>
</div>
</React.Fragment>
)
The data is displayed properly, But when I try to use state for data and use setState(), it causes another error so, I opted for this approach.
Sry, I forgot in hurry
const colHeads = columns.map((cl)=>{
return cl==='kills'||cl==='rank'||cl==='wallet'
? {title:colValues[cl],field:cl,type:'numeric',editable: 'onUpdate'}
: {title:colValues[cl],field:cl,editable: 'never'}
});const colData = players && players.map((pl,ind)=>{ let cp={} columns && columns.map((cl,cind)=>{ return cl==='srno'? cp[cl]=players.indexOf(pl)+1 : cp[cl]=pl[cl] }) return cp; }) const tRef = React.useRef(); const editF = { onRowAdd:null, onRowUpdate:(newData,oldData)=> new Promise((resolve,reject)=>{ setTimeout(()=>{ let data = colData; console.log(state) let inx = data.indexOf(oldData); newData['kills']=parseInt(newData['kills']) newData['wallet']=parseInt(newData['wallet']) newData['rank']=parseInt(newData['rank']) data[inx] = newData; resolve(); },1000) }), onRowDelete : null }; const tRF = ()=>{ setState(state) } return( <React.Fragment> <div> <MaterialTable tableRef={tRef} title="Players" columns={colHeads} data={colData} editable={isEditing? editF : null} /> <button onClick={() => { tRef.current.onQueryChange(); }} > ok </button> <div hidden={!bttnname}> <button onClick={()=>tRF()} className='waves-effect waves-light btn hoverable'>{bttnname}</button> </div> </div> </React.Fragment> )The data is displayed properly, But when I try to use state for data and use setState(), it causes another error so, I opted for this approach.
It's hard to follow what your doing, but it seems like you don't need to use data in this manner in the first place. If you aren't dealing directly with remote data like in the previous example, you should fix your state problem. Good luck!
Sry, I forgot in hurry
const colHeads = columns.map((cl)=>{
return cl==='kills'||cl==='rank'||cl==='wallet'
? {title:colValues[cl],field:cl,type:'numeric',editable: 'onUpdate'}
: {title:colValues[cl],field:cl,editable: 'never'}
});const colData = players && players.map((pl,ind)=>{ let cp={} columns && columns.map((cl,cind)=>{ return cl==='srno'? cp[cl]=players.indexOf(pl)+1 : cp[cl]=pl[cl] }) return cp; }) const tRef = React.useRef(); const editF = { onRowAdd:null, onRowUpdate:(newData,oldData)=> new Promise((resolve,reject)=>{ setTimeout(()=>{ let data = colData; console.log(state) let inx = data.indexOf(oldData); newData['kills']=parseInt(newData['kills']) newData['wallet']=parseInt(newData['wallet']) newData['rank']=parseInt(newData['rank']) data[inx] = newData; resolve(); },1000) }), onRowDelete : null }; const tRF = ()=>{ setState(state) } return( <React.Fragment> <div> <MaterialTable tableRef={tRef} title="Players" columns={colHeads} data={colData} editable={isEditing? editF : null} /> <button onClick={() => { tRef.current.onQueryChange(); }} > ok </button> <div hidden={!bttnname}> <button onClick={()=>tRF()} className='waves-effect waves-light btn hoverable'>{bttnname}</button> </div> </div> </React.Fragment> )The data is displayed properly, But when I try to use state for data and use setState(), it causes another error so, I opted for this approach.
It's hard to follow what your doing, but it seems like you don't need to use data in this manner in the first place. If you aren't dealing directly with remote data like in the previous example, you should fix your state problem. Good luck!
Really Thanks, for the quick reply. I'll go with it then!
Just a sidenote. If you want to trigger the data reload on the table from one of your action button handlers which holds some async functions, and you have a problem like your reference is null, than the following might help you:
// Example is for a functional component
const yourRef = React.createRef()
// ...
tableRef: {yourRef},
actions: {[
rowData => ({
// ...
onClick: (event, rowData) => {
const scopedRef = yourRef.current
anAsyncFunction(/*...*/).then(() => scopedRef.onQueryChange())
}
})
]}
// ...
Most helpful comment
Hi @billBeOK ,
Your requirement makes sense. I resolved it with tableRef with new version 1.28.0