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

Download CSV is broken with customBodyRender #973

Closed
GuyShaanan opened this issue Oct 2, 2019 · 8 comments · Fixed by #964
Closed

Download CSV is broken with customBodyRender #973

GuyShaanan opened this issue Oct 2, 2019 · 8 comments · Fixed by #964
Assignees
Labels

Comments

@GuyShaanan
Copy link
Contributor

GuyShaanan commented Oct 2, 2019

A continuation of #963 and (possibly) reopening of #275 .

Expected Behavior

Having a customBodyRender should produce CSV file that looks exactly like shown in UI.

Current Behavior

Downloaded csv (in case of columns with customBodyRender) produces out-of-order output.
Like if UI shows:

id name char
0 a0 0
1 a1 1
2 a2 2

the downloaded CSV shows:

id name char
0 a0 0
1 a1 7
2 a2 4

Steps to Reproduce (for bugs)

https://codesandbox.io/s/suspicious-feynman-mf925

Your Environment

Tech Version
Material-UI 3.9.3
MUI-datatables 2.11.1
React 16.8.6
browser *

Since React 0.14, Dan Abramov says they are tagging react components to be easilty identified. Maybe this can help.

@gabrielliwerant
Copy link
Collaborator

Thanks for opening. I've been looking into the react object identification as part of this, but it turns out this issue is not exactly that. It was a failure of the logic to account for the displayed data index. There was no problem until the data was sorted for a custom render, but once sorted, the index isn't maintained. I've added a fix for that to the PR I opened for the other issue as they involve the same line of code.

@GuyShaanan
Copy link
Contributor Author

Hi. Thank you so much for being so responsive.

Unfortunately, this needs to be re-opened as it is not solved in 2.12.0.
The reproduce steps are a bit complicated but now they truly expose the issue: https://codesandbox.io/s/pedantic-rain-b4j6o

On

return typeof column === 'object' && column !== null && !Array.isArray(column)

when column is indeed a React component, it looks like this:

[{}]
0: {$$typeof: Symbol(react.element), key: "17", ref: null, props: {}, type: ƒ,}
length: 1
__proto__: Array(0)

and such it is an array and it fails the check, and doesn't pass the original value from data (data[row.index].data[i]) but the column itself.

The output of categories column in CSV should match the one in the UI.

@gabrielliwerant
Copy link
Collaborator

gabrielliwerant commented Oct 3, 2019

The way you are using it now is actually unsupported behavior. You have to return either a react component or a string from customBodyRender (plain component, not array of components).

@GuyShaanan
Copy link
Contributor Author

Thanks. I guess I need to find a workaround for this as this is a show stopper.
What is the rational behind this differentiation? Why not always pass the original values to the create CSV function?

@gabrielliwerant
Copy link
Collaborator

What is it you are trying to do exactly? Seems to me that you should be able to do just about anything with a component. If you need a list of something in the cell, then wrap a component around your map. Just make sure there's a component around everything in the customBodyRender.

@GuyShaanan
Copy link
Contributor Author

wrap a component around your map

Yep, that's the workaround. It works now.
Thanks.

@gabrielliwerant
Copy link
Collaborator

Ok, glad it works! The render functions are only set up to pass components and strings, It's just how they work, but I think they should provide enough for most use cases with those options.

@retax3
Copy link

retax3 commented Mar 5, 2020

My solution was create 2 columns one with custom body render (options:{download:false}), and second column is a normal but hidden with display "false"
like this

{
      name: "LOS",
      field: "los",
      options: {
        filter: false,
        sort: true,
        download: false,
        customBodyRender: item => {
          return (
            <label style={item.los > 0 ? { color: "red" } : { color: "" }}>
              {item.los}
            </label>
          );
        }
      }
    },
    {
      name: "LOS",
      field: "los",
      options: {
        filter: false,
        sort: true,
        display: "false"
      }
    },

with this we can get the data to csv download!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
3 participants