Reputation: 175
I am trying to add an option to download data as a CSV file inside my component. However, the below code sometimes prints a garbage character 
and works other times. I don't understand what I am doing wrong here. I tried to follow the example provided here: https://github.com/react-csv/react-csv#readme
Here is my code
import React, { useState } from "react";
import axios from "axios";
import {
Card,
CardHeader,
CardTitle,
DropdownItem,
DropdownMenu,
DropdownToggle,
Table,
UncontrolledDropdown,
Progress
} from "reactstrap";
import { MoreHorizontal } from "react-feather";
import { CSVLink } from "react-csv";
const Languages = () => {
const [data, setData] = useState([]);
return (
<Card className="flex-fill w-100">
<CardHeader>
<div className="card-actions float-right">
<UncontrolledDropdown>
<DropdownToggle tag="a">
<MoreHorizontal />
</DropdownToggle>
<DropdownMenu right>
<DropdownItem><CSVLink data={data} filename={'my-file.csv'} asyncOnClick={true}
onClick={(event, done) => {
axios.get("http://localhost:9091/api/returnIndices", {
params: {
view: 'Series',
bucket: '3_7',
group: 'Ratings',
metric: 'Price Return',
download: true
}
}).then((response) => {
const data = response.data.payload;
console.log(data);
setData(JSON.parse(data));
done(false); // REQUIRED to invoke the logic of component
});
}}>Download me</CSVLink></DropdownItem>
</DropdownMenu>
</UncontrolledDropdown>
</div>
<CardTitle tag="h5" className="mb-0">
Languages
</CardTitle>
</CardHeader>
</Card>
);
}
export default Languages;
Upvotes: 2
Views: 3071
Reputation: 175
I ended up following the post here https://github.com/react-csv/react-csv/issues/189
Here is what I ended up doing
CsvExport.js
import React, { useState, useEffect, useRef } from 'react';
import { CSVLink } from 'react-csv';
import axios from "axios";
import { config } from '../../../config';
const CsvExport = ({view, bucket, group, metric, startDateMs, endDateMs}) => {
const [csvData, setCsvData] = useState(false);
const csvInstance = useRef();
useEffect(() => {
if (csvData && csvInstance.current && csvInstance.current.link) {
setTimeout(() => {
csvInstance.current.link.click();
setCsvData(false);
});
}
}, [csvData]);
return (
<div type="button" tabIndex="0" role="menuitem" className="dropdown-item">
<div
onClick={async () => {
const newCsvData = await axios.get(config.serviceHost + config.downloadPath, {
params: {
view: view,
bucket: bucket,
group: group,
metric: metric,
startDate: startDateMs,
endDate: endDateMs,
download: true
}
});
// console.log(newCsvData.data.payload);
const filename = [view, bucket, group, metric, Date.now()].join('_') + '.csv';
setCsvData({
data: JSON.parse(newCsvData.data.payload),
filename: filename
});
}}
>
Download as CSV
</div>
{csvData ?
<CSVLink
data={csvData.data}
filename={csvData.filename}
ref={csvInstance}
/>
: undefined}
</div>
);
};
export default CsvExport;
Languages.js
<div className="card-actions float-right">
<Dropdown isOpen={this.state.dropdownOpen} toggle={this.toggle}>
<DropdownToggle tag="a">
<MoreHorizontal />
</DropdownToggle>
<DropdownMenu right>
<CsvExport metric={metric} view={view} bucket={bucket} group={group} startDateMs={this.convertToMs(this.props.startDate)} endDateMs={this.convertToMs(this.props.endDate)}/>
</DropdownMenu>
</Dropdown>
</div>
Upvotes: 3