Code Monkey home page Code Monkey logo

Comments (19)

stevehanson avatar stevehanson commented on May 19, 2024 124

The downside of using the CSVDownload component is that it doesn't accept the filename prop. I ended up getting this to work by setting up a regular button, which, when clicked, fetches the data and then triggers a click of a hidden CSVLink:

class MyCsvLink extends React.Component {
  csvLink = React.createRef()
  state = { data: [] }

  fetchData = () => {
    fetch('/mydata').then(data => {
      this.setState({ data }, () => {
        // click the CSVLink component to trigger the CSV download
        this.csvLink.current.link.click()
      })
    })
  }

  render() {
    return (
      <div>
        <button onClick={this.fetchData}>Download CSV</button>

        <CSVLink
          data={this.state.data}
          filename="data.csv"
          className="hidden"
          ref={this.csvLink}
          target="_blank" 
       />
    </div>
    )
  }
}

It'd be nice if this plugin exposed a JS API that could be used to trigger a download instead of requiring the CSVDownload or CSVLink components to be used.

from react-csv.

Beatrice084 avatar Beatrice084 commented on May 19, 2024 10

This worked for me:
<CSVLink data={[["Test", 1], ['Test', 2]].toString()} filename={this.props.title}><Button>Download CSV</Button></CSVLink>

from react-csv.

rsxdalv avatar rsxdalv commented on May 19, 2024 6

Given that the function for data property does not appear to actually work, I suggest removing it from the docs.

from react-csv.

iassainov avatar iassainov commented on May 19, 2024 5

In case anyone is having only a Ôªø symbol in CSV, put your this.csvLink.current.link.click() inside of the setTimeout statement like so:

setTimeout(() => {
   this.csvLink.current.link.click();
});

from react-csv.

garedean avatar garedean commented on May 19, 2024 4

@abdennour I've tried following the 'Async + data function' approach using react-csv version 2.2.2, copying the example closely (but using my own async function/request), and reliably get the following error:

dev-1214.js:1 Uncaught TypeError: Data should be a "String", "Array of arrays" OR "Array of objects" 
    at toCSV (core.js:1:3429)
    at buildURI (core.js:1:3625)
    at CSVLink.buildURI (Link.js:1:2399)
    at CSVLink.render (Link.js:1:4230)
    at finishClassComponent (one-vui-9e10834c-dev.js:1:566704)
    at updateClassComponent (one-vui-9e10834c-dev.js:1:566126)
    at beginWork (one-vui-9e10834c-dev.js:1:584296)
    at HTMLUnknownElement.callCallback (one-vui-9e10834c-dev.js:1:422607)
    at HTMLUnknownElement.nrWrapper (dev-1214.js:1:30034)
    at Object.invokeGuardedCallbackDev (one-vui-9e10834c-dev.js:1:422975)

A stripped-down version of my implementation:

export default class DownloadUsers extends Component {
  constructor(props) {
    super(props);

    this.state = {
      listOfUsers: [],
    };
  }

  fetchData = (event, done) => {
    Querier.query({
      query: someQuery
    }).then(({ data }) => {
      const users = data.listOfUsers;
      this.setState({ listOfUsers });
      done(true);
    });
  };

  dataFromListOfUsersState = () => {
    return this.state.listOfUsers;
  };

  render() {
    return (
      <CSVLink data={this.dataFromListOfUsersState} asyncOnClick={true} onClick={this.fetchData}>
        Download CSV
      </CSVLink>
    );
  }
}

Any ideas before I file an issue? And thank you for your work on this excellent package.

from react-csv.

mriccid avatar mriccid commented on May 19, 2024 3

@christianallred the problem with that solution is that it will potentially download the CSV every time a render occurs after fetching data.

I don't think that this component should be responsible for fetching data, so the solution to this problem needs to exist outside of this library.

@arpitprod assuming that this component exists on a page that has to fetch some data before, you could try something like this:

  • Fetch the data required for the page to render
  • Fetch the data for the CSV, but don't let it prevent the rest of the page from loading
  • Render the page, but display a loader in place of the CSV download button
  • When the data for the CSV has returned, render the CSV button properly

This pattern may help you with this solution: https://lucasmreis.github.io/blog/simple-react-patterns/

from react-csv.

git-angelo avatar git-angelo commented on May 19, 2024 2

In case anyone is having only a Ôªø symbol in CSV, put your this.csvLink.current.link.click() inside of the setTimeout statement like so:

setTimeout(() => {
   this.csvLink.current.link.click();
});

I confirm, my code was based on this answer: https://stackoverflow.com/a/53558566 and I needed to add a setTimeout to make it work. I did not find a better solution... :(

from react-csv.

anshuporwal01 avatar anshuporwal01 commented on May 19, 2024 2

Follow the given Point -
Define

  1. const ref = React.useRef(null)
    const [exportData, setExportData] = useState([])

const onClickExport = async () => {
showLoadingModal()
let data = await api.index(userId)
setExportData(data)
hideLoadingModal()
ref.current.click()
}
3.
<> <UiButton color="link" icon="download" size="small" onClick={onClickExport} /> </>
4.
<CSVLink data={exportData} filename={fileName}> <span ref={ref}></span> </CSVLink>

from react-csv.

christianallred avatar christianallred commented on May 19, 2024 1

This is already doable via CSVDownload element.

https://github.com/abdennour/react-csv#2-csvdownload-component

    <div>
        <Button onClick={this.fetchData}>Button</Button>
        {this.state.data != null ? <CSVDownload data={this.state.data} target="_blank" /> : null }
    </div>

Disclosure: i have not tried this.. but a quick review of the documentation would suggest my code above shoudl work.

from react-csv.

garedean avatar garedean commented on May 19, 2024 1

@kundan621 I haven't found a solution to this particular issue however there is a workaround to handle async data loading following the approach described here or here.

from react-csv.

divyabiyani avatar divyabiyani commented on May 19, 2024

@christianallred Doesn't this solution also will require user to click 2 buttons to download a single csv?

@arpitprod: Hey, I am also working on a similar issue. Did you come across a solution for this?

from react-csv.

davecat avatar davecat commented on May 19, 2024

It should be written like this:
{ this.state.boolean?<CSVDownload target="_parent" data={data}></CSVDownload>:''}
onClick=(){ this.setState({ boolean: true },() =>{ this.setState({ boolean: false }) }) }

from react-csv.

dixitk13 avatar dixitk13 commented on May 19, 2024

this is what I tried and it works for me: (I use React+Redux)
P.S: This is what @christianallred suggests in the initial comment as well, using react state.

Made a stateless component like this:

const CSVButton = ({ data, fetchCSVData, fileName }) => {
  
  if (_.isEmpty(data)) {
    return (
      <span onClick={fetchCSVData} className="csv-download">
        CSV <Icon icon="download" />
      </span>
    )
  } else {
    return (
      <CSVDownload
        className="csv-download"
        target="_self"
        filename={fileName}
        data={data}
      />
    )
  }
}

the fetchCSVData action, fetches the data in async mode, and dispatches two actions. one for setting the data field and other which un-sets/resets the data field.

What really happens is, the state change triggers the reload of the stateless component and CSVDownload is rendered in the DOM to initiate the download functionality. The state is reset then to remove the specific element out of the DOM

from react-csv.

vikapath avatar vikapath commented on May 19, 2024

@stevehanson is CSVLink component working on firefox as well ? i am having some issues with that.

from react-csv.

mccabemj avatar mccabemj commented on May 19, 2024

A couple of great solutions to the question here. Hopefully @arpitprod they answer your question, please re-open if not. @vikapath please open a new issue if your still having issues with Firefox

from react-csv.

CallumHemsley avatar CallumHemsley commented on May 19, 2024

@stevehanson I'm trying your approach, however when I go to open the csv e.g in excel, the index.html HTML is just shown..

Any idea how to fix this? I'm doing exactly the same as you, and if I console log the this.state.data I see the data..

from react-csv.

abdennour avatar abdennour commented on May 19, 2024

Check README.md, and specifically the section 🔬 Async + data function. Enjoy!
Available since [email protected]

from react-csv.

kundan621 avatar kundan621 commented on May 19, 2024

@abdennour
I am also facing the same issues. Example code itself is not working and breaking screen by throwing Data should be a "String", "Array of arrays" OR "Array of objects"

@garedean Did you find any solution?

from react-csv.

kundan621 avatar kundan621 commented on May 19, 2024

@kundan621 I haven't found a solution to this particular issue however there is a workaround to handle async data loading following the approach described here or here.

Thank you @garedean :)

from react-csv.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.