Reputation: 223
In my application I need to save on my computer a CSV file which comes from an API response. The function which sends POST request is (I am using Redux):
export const postCsv = sensorData => (dispatch, getState) => {
const token = getState().auth.token;
// Headers
const config = {
headers: {
'Content-Type': "application/json"
}
}
// If token exists, add to headers config
if (token) {
config.headers['Authorization'] = `Token ${token}`
}
// Post request to API
axios.post(`${baseURL}/sensors_data/csv`, sensorData, config)
.then(res => {
console.log(res);
if (res.status === 200) {
dispatch({
type: POST_CSV,
payload: res.data
})
}
})
.catch(err => {
console.log(err.response);
})
}
and response from API is:
I execute the postCsv function after a button click. As you can see, the response code is 200 and every data has been sent correctly. I just don't know what should I do to download and save the file. Can anyone help?
Upvotes: 4
Views: 20309
Reputation: 513
const downloadFile = () => {
const url = window.URL.createObjectURL(new Blob([response.data]))
const link = document.createElement('a')
link.href = url
link.setAttribute('download', "yourfilename.csv")
document.body.appendChild(link)
link.click()
link.remove()
}
Upvotes: 16
Reputation: 39482
As suggested by @cocco in this thread, you could dynamically generate an anchor with the download
attribute.
NOTE: For the sake of simplicity, I'll demo getting the data part form an API using a useEffect
and a fake HttpClient
service that has a static get
method that returns the data. But hope you get the general idea.
import React, { useState, useEffect } from "react";
import HttpClient from "./HttpClient";
import "./style.css";
export default function App() {
const [dataInCSV, setDataInCSV] = useState("");
useEffect(() => {
HttpClient.get().then(res => setDataInCSV(res));
}, []);
return (
<div>
{dataInCSV && (
<a
href={`data:text/csv;charset=utf-8,${escape(dataInCSV)}`}
download="filename.csv"
>
download
</a>
)}
</div>
);
}
Here's a Working Sample Code Example for your ref.
Upvotes: 6