I want to separate controllers and services in my Express app, currently, I have a service that generates an XLSX file using ExcelJS, I want to reuse the service so, I don't want to pass the response object to the service, is there a way I can return the file from the service to the controller?
Right now I have the following
const generateXLSX = (res, data) => {
let baseFile = "path/to/template.xlsx";
let wb = new Excel.Workbook();
wb.xlsx
.readFile(baseFile)
.then(async () => {
// add data to template
}
await wb.xlsx.write(res);
res.end();
})
.catch((err) => {
console.log(err);
res.status(500);
});
};
In this function I'm using the response object in the service, I want to know if there's a way to return the file without using write(res), and send it in the controller
CodePudding user response:
Your generateXLSX
function could return a "pass-through" readable stream which you then pipe into the res
object. Something like
const {PassThrough} = require("stream");
function generateXLSX(data) {
let baseFile = "path/to/template.xlsx";
let wb = new Excel.Workbook();
let readable = new PassThrough();
wb.xlsx
.readFile(baseFile)
.then(async function() {
// add data to template
await wb.xlsx.write(readable);
readable.end();
})
.catch((err) => {
readable.destroy(err);
});
return readable;
}
app.use("/path", function(req, res) {
generateXLSX(req.query.data).pipe(res);
});