I have an endpoint which streams a csv as a response. It’s not from a file but a direct DB => Format => Append to Stream process. Here is how it is written:
try {
const datetime = new Date();
res.set('Expires', dateTime);
res.set('Cache-Control', 'max-age=0, no-cache, must-revalidate, proxy-revalidate');
res.set('Last-Modified', `${datetime} GMT`);
res.set('Content-Type', 'application/octet-stream');
res.set('Content-Disposition', 'attachment;filename=Data.csv');
res.set('Content-Transfer-Encoding', 'binary');
res.write(objectToCSV(headers));
for (const dateChunk of dateChunks) {
const rawData = await getData(dateChunk.from, dateChunk.to);
// Skip if empty
if (!data.length) continue;
// Stream it
res.write(`\n${objectArrayToCSV(rawData)}`);
}
res.end();
} catch (error) {
logger.error('Export made error', { error });
throw new Error('EXPORT_FAILURE');
}
The endpoint works wonder and streams the csv as a download in the browser.
But now I want to configure it as a Smart Action. This means that I have to handle the request through a Forest Admin endpoint.
Liana.collection('myCollection', {
actions: [
{
name: 'Export CSV',
fields: [{ field: 'fromDate', type: 'Dateonly' }, { field: 'toDate', type: 'Dateonly' }],
type: 'global',
download: true,
},
],
});
static exportDataCSV(req, res) {
const fromDate = req.body.data.attributes.values.fromDate;
const toDate = req.body.data.attributes.values.toDate;
api.exportDataCSV(fromDate, toDate).then(apiRes => {
res.status(200);
res.set({
'Access-Control-Expose-Headers': 'Content-Disposition',
'Content-Disposition': `attachment; filename="data.csv"`,
'Content-Type': 'text/csv; charset=utf-8',
});
apiRes.data.pipe(res);
});
}
The file download doesn’t stream, it freezes, waits for the entire file to be downloaded and outputs it with the wrong filename.
Please note that the following works as intended, it’s the same without the Forest Admin layer:
const express = require('express');
const axios = require('axios');
const app = express();
const port = 3008;
app.get('/test', async (req, res) => {
const apiRes = await axios.get('http://localhost:3000/myData/exportCSV?fromDate=2018-01-01&toDate=2020-05-01', {
responseType: 'stream',
});
res.status(200);
res.set({
'Content-Disposition': `attachment; filename="data.csv"`,
'Content-Type': 'text/csv; charset=utf-8',
});
apiRes.data.pipe(res);
});
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`);
});
- Package Version: 10.22.0
- Express Version: