Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redux with Remote Data #630

Closed
ismaildervisoglu opened this issue May 29, 2019 · 30 comments
Closed

Redux with Remote Data #630

ismaildervisoglu opened this issue May 29, 2019 · 30 comments
Assignees
Labels
help wanted Extra attention is needed

Comments

@ismaildervisoglu
Copy link

ismaildervisoglu commented May 29, 2019

I'm pulling data into the table using redux. It works seamlessly when I send the data directly without paging, but it does not
  {
data: // your data array
  page: // current page number
  totalCount: // total page number
}
I get an error when I try to send it this way.

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

Hi @ismaildervisoglu

Can you share your table usage code, please?

@mbrn mbrn self-assigned this May 29, 2019
@mbrn mbrn added the help wanted Extra attention is needed label May 29, 2019
@ismaildervisoglu
Copy link
Author

ismaildervisoglu commented May 29, 2019

Table Code:

<MaterialTable
            columns={columnss}
            icons={{
              Check: () => <Check />,
              Export: () => <SaveAlt />,
              Filter: () => <FilterList />,
              FirstPage: () => <FirstPage />,
              LastPage: () => <LastPage />,
              NextPage: () => <ChevronRight />,
              PreviousPage: () => <ChevronLeft />,
              Search: () => <Search />,
              ThirdStateCheck: () => <Remove />,
              ViewColumn: () => <ViewColumn />,
              DetailPanel: () => <ChevronRight />,
            }}
            data={data}
            options={{
              search: false,
              selection: true,
              toolbar: false,
              showTitle: false,
              headerStyle: { padding: '4px 8px 4px 8px' },
              paginationType: 'stepped',
            }}
            components={{
              Cell: props => (
                <MTableCell {...props} style={{ padding: '4px 8px 4px 8px' }} />
              ),
            }}
            onSelectionChange={(rows) => { this.changeSelection(rows); }}
            onChangeRowsPerPage={(value) => this.onChangeRowsPerPage(value)}
            onChangePage={(page) => this.onChangePage(page)}
          />

Reducer code:

import {
  RECEIVE_STUDENT_LIST_TABLE_DATA,
  REQUEST_STUDENT_LIST_TABLE_DATA,
} from '../actions/studentListTableAction';

const initialState = {
  userListTableData: [],
  userListTableDataLoading: false,
};

export default function (state = initialState, action) {
  switch (action.type) {
    case REQUEST_STUDENT_LIST_TABLE_DATA: {
      return Object.assign({}, state, {
        userListTableDataLoading: true,
      });
    }
    case RECEIVE_STUDENT_LIST_TABLE_DATA: {
      return Object.assign({}, state, {
        userListTableData: {
          data: action.data.resultContainer,
          page: 2,
          totalCount: 100,
        },
      });
    }
    default:
      return state;
  }
}

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

What is data that you set to MT?

Actually MT does not care you retrieve data from redux store or state.

@ismaildervisoglu
Copy link
Author

userListTableData: {
data: action.data.resultContainer,
page: 2,
totalCount: 100,
},

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

you should give a data array or function that returns a promise. This is not proper way to give data to MT.

Use
data={userListTableData.data}
or
data={query =>
new Promise((resolve, reject) => {
resolve(userListTableData
})
}

@ismaildervisoglu
Copy link
Author

Ok. When I give data this way data={userListTableData.data} retrieves the data, but does not get page and totalCount

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

Yes. This means MT will manage pagination.

@mbrn mbrn closed this as completed May 29, 2019
@ismaildervisoglu
Copy link
Author

but when I can't get totalCount or page i cannot print the size of the data 16-20 of TotalCount

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

You must set totalCount. Pagination works according to totalCount

@ismaildervisoglu
Copy link
Author

ismaildervisoglu commented May 29, 2019

I'm trying to ask you that. How should I give totalCount? Give an "TypeError: data.map is not a function" when I give the object I sent to the data in previous messages.

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

data={query =>
new Promise((resolve, reject) => {
resolve({
data: // your data array
page: // current page number
totalCount: // total page number
})
}

@ismaildervisoglu
Copy link
Author

When I give data like this:

data={query => new Promise((resolve, reject) => {
            resolve({
              data: userListTableData.data,
              page: userListTableData.page,
              totalCount: userListTableData.totalCount,
            });
          })
          }

It gives an ERROR:

Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

Check the render method of MaterialTable.

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

This is not data related error. Please check your imports

@ismaildervisoglu
Copy link
Author

ismaildervisoglu commented May 29, 2019

I found the error. But the table should be empty first and then click on the button, then access the data and fill the table but the data in the table is not updated.

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

Please check data in console. It should work.

@ismaildervisoglu
Copy link
Author

I checked the data coming right. But there is a continuous circularprogrees icon in the table.

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

Sorry @ismaildervisoglu ,

I could not help you without code. Please check examples in documentation

@ismaildervisoglu
Copy link
Author

ismaildervisoglu commented May 29, 2019

Table Container:

<Table
          changeSelection={this.tableSelection}
          addArchivedButtonBool
          data={userListTableData}
          columns={t('students.students.student_list_table_columns', { returnObjects: true })}
          changeRowsPerPage={this.changeRowsPerPage}
          changePage={this.changePage}
        />

Table Component:

<MaterialTable
           columns={columnss}
           isLoading={false}
           icons={{
             Check: () => <Check />,
             Export: () => <SaveAlt />,
             Filter: () => <FilterList />,
             FirstPage: () => <FirstPage />,
             LastPage: () => <LastPage />,
             NextPage: () => <ChevronRight />,
             PreviousPage: () => <ChevronLeft />,
             Search: () => <Search />,
             ThirdStateCheck: () => <Remove />,
             ViewColumn: () => <ViewColumn />,
             DetailPanel: () => <ChevronRight />,
           }}
           data={query => new Promise((resolve, reject) => {
             resolve({
               data: data.data,
               page: data.page,
               totalCount: data.totalCount,
             });
           })
           }
           options={{
             search: false,
             selection: true,
             toolbar: false,
             showTitle: false,
             headerStyle: { padding: '4px 8px 4px 8px' },
             paginationType: 'stepped',
           }}
           onSelectionChange={(rows) => { this.changeSelection(rows); }}
           onChangeRowsPerPage={(value) => this.onChangeRowsPerPage(value)}
           onChangePage={(page) => this.onChangePage(page)}
         />

@mbrn
Copy link
Owner

mbrn commented May 29, 2019

If you use remote data feature and change data manually, you should call onQueryChange function of table manually after data changes. Please check documentation examples of remote data feature. It has an example of tableRef usage.

@paillave
Copy link

paillave commented Jun 1, 2019

I understand the solution, but it is far to be simple. I believe that given the fact that redux is one of the most recommended architecture for react, the paging feature should be more "redux friendly". Actually the problem is exactly the same regarding to the editable feature that is 100% not "redux friendly". I can take care of this improvement if you want.

@mbrn
Copy link
Owner

mbrn commented Jun 5, 2019

Hi @paillave

Any contribution is apprepriatable:). MT is controlled component for paging. If you want to make it uncontrolled you can override the paging component.

@lfernando-silva
Copy link

lfernando-silva commented Jun 10, 2019

I made a trick to handle pagination handling the TablePagination component, controlling manually the pagination on the state, but just for a temporary solution. As @paillave said, is not really redux-friendly.

                   data={props.data} 
                   components={{
                        Pagination: (componentProps) => <TablePagination
                            {...componentProps}
                            count={response.count}
                            page={page}
                            rowsPerPage={skip}
                            onChangePage={(evt, page) => {
                                let nextPage = page + 1
                                this.setState({page: nextPage})
                                props.doList({ order: 'created_at,DESC', limit: 10, offset: nextPage * skip })
                            }}
                        />
                    }}

@paillave
Copy link

As this may be the best material grid, I am trying to work on it to make it more redux friendly.

@Monfernape
Copy link

@paillave any updates on this?

@raikusy
Copy link

raikusy commented Apr 19, 2020

Can anyone provide a good example for using MT with redux remote data? Me along many other people having trouble with that.

@sebaranowski
Copy link

Luckily my response header contains x-total-count which allows me to do this (dont like it but it works):

const getData = (query): Promise<QueryResult<ITodo>> => {
    return new Promise((resolve, reject) => {
      Promise.resolve(props.getEntities(query.page, query.pageSize)).then((data) => {
        const temp: IResponseData<ITodo> = data as unknown as IResponseData<ITodo>; // hmm..
        const axRes: AxiosResponse = temp.value;
        const totalCount = Number(axRes.headers['x-total-count']);

        resolve({
          data: axRes.data,
          page: query.page,
          totalCount,
        });
      });
    });
  };
 <MaterialTable
        title=""
        data={getData}
        columns={[
          ...

@cuiziang
Copy link

cuiziang commented Jul 25, 2020

Try mine with Redux and hook base on @sebaranowski.

It works for me.

 const getData = query => {
        return new Promise((resolve, reject) => {
            Promise.resolve(dispatch(fetchAllItems(query))
                .then((data) => {
                    const TableData = data.payload.items.map(r => ({ ...r }))
                    const totalCount = data.payload.totalCount; // Or from x-total-count in header

                    resolve({
                        data: TableData,
                        page: query.page,
                        totalCount,
                    });
                }))
        });
    };

@matiaslato
Copy link

in other pro

Try mine with Redux and hook base on @sebaranowski.

It works for me.

 const getData = query => {
        return new Promise((resolve, reject) => {
            Promise.resolve(dispatch(fetchAllItems(query))
                .then((data) => {
                    const TableData = data.payload.items.map(r => ({ ...r }))
                    const totalCount = data.payload.totalCount; // Or from x-total-count in header

                    resolve({
                        data: TableData,
                        page: query.page,
                        totalCount,
                    });
                }))
        });
    };

in other proyect I use this with thunk buttttt with sagas? i cant find a way

@francisngo
Copy link

@mbrn

If you use remote data feature and change data manually, you should call onQueryChange function of table manually after data changes. Please check documentation examples of remote data feature. It has an example of tableRef usage.

Can you show where in documentation? I only see it being used as an action button but not onChangePage

@alam7860
Copy link

plz tell me about pegination in material table with firebase database (remote data) in react-hook redux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests