How to download the pdf file after generated in nodejs - node.js

I'm building a web application in Node.js 10.x and angular 6.x. I wish to generate a PDF and download it via browser.
angular 6.x
generatePDF(params): any {
return this.http.post(this.url('generatePDF'), params, this.getRequestOptions())
.pipe(map((res: any) => {
return res;
})
);
}
Node.js
async generatePDF(options = { format:'A4' }) {
return new Promise((resolve, reject) => { ejs.renderFile(this.templateName, this.data, (err, res) => {
if (err) {
return reject(err);
}
pdf.create(res, options)
.toFile(this.fileName, (err, res) => {
if (err) {
return reject(err);
}
resolve(res);
});
});
});
}

I have solved this problem as follows.
Node.js
let pdffilename = username + '_' + gameName.replace(/ /g, "_") + '.pdf';
pdfReport = new Report(gameName, ejsfilename, pdffilename, refined_score);
await pdfReport.generatePDF();
res.sendFile(pdfReport.fileName);

After Creation of PDF path , you can use the following code to download your file
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Headers', 'X-Requested-With');
res.header('content-type', 'application/pdf');
res.download(PDF_PATH, PDF_NAME + '.pdf');

Related

how to send response only after mv library on nodejs completes. Wrapping in promise doesn't work

I'm trying to setup an endpoint that takes a file through a multipart post request, and saves it into a specific directory using formidable and https://github.com/andrewrk/node-mv. And then upon completion of saving all of the files, I want to respond with a list of all of the files in that directory for rendering. the thing is the response seems to be sent before the directory listing is updated. I tried wrapping the mv operations into a promise and then responding in a then block to no avail. Any help would be much appreciated!
app.post("/api/v1/vendor/:id/menu", (req, res, next) => {
const id = req.params.id;
const form = formidable({ multiples: true, keepExtensions: true });
form.parse(req, (err, fields, files) => {
if (err) {
next(err);
return;
}
if (!Array.isArray(files.image)) {
files = [files.image];
}
let filelist;
const proms = files.map((file) => {
const dst = `pics/${id}/${file.name}`;
new Promise((resolve, reject) => {
mv(file.path, dst, { mkdirp: true }, (err) => {
if (err) {
console.error("error: ", err.status);
reject(err);
}
console.log("done moving");
resolve();
});
});
});
Promise.all(proms).then(() => {
console.log('now reading dir...');
filelist = fs.readdirSync("pics/" + id);
res.send(filelist);
});
});
});
I think we're missing the return keywork before new Promise. You can check the proms variable if it contains the list of promises or not.
const proms = files.map((file) => {
const dst = `pics/${id}/${file.name}`;
new Promise((resolve, reject) => {
mv(file.path, dst, { mkdirp: true }, (err) => {
if (err) {
console.error("error: ", err.status);
reject(err);
}
console.log("done moving");
resolve();
});
});
});
For me, it should be :
const proms = files.map((file) => {
const dst = `pics/${id}/${file.name}`;
return new Promise((resolve, reject) => {
mv(file.path, dst, { mkdirp: true }, (err) => {
if (err) {
console.error("error: ", err.status);
reject(err);
}
console.log("done moving");
resolve();
});
});
});

download JSON file in node Js

I am creating a json file, but not sure how to download it.
here is my code
let jsonExport= directory path;
exportTemp (name, title, id) {
let obj = new Array() ;
obj.push({Title: name, Prefix:title, UserId:id });
let file_name= jsonExport + name + ".json"
fs.writeFile(file_name, JSON.stringify(obj, null, 4), (err, response) => {
if (err) {
console.error(err);
return;
};
console.log("File has been created");
});
return (file_name);
};
If you're using express, you can simply do it like this
res.download(file_name);
or without express
app.get('/downloadFile/', (req, res) => {
var files = fs.createReadStream(file_name);
res.writeHead(200, {'Content-disposition': 'attachment; filename=demo.pdf'});
files.pipe(res)
})

Download file from server (Nodejs Express > React)

how can i send a file(docx) to a user ?
this is my server code :
app.get('/api/topic/file/:id', function (req, res, next) {
Topic.findByIdAndUpdate(req.params.id)
.exec()
.then((topic) => {
let filepath = topic.news_file[0]
console.log('filepath', filepath)
res.download(filepath, topic.name + '.docx', function (err) {
if (err) {
console.log('api get file err ', err);
} else {
// decrement a download credit, etc.
}
});
}).catch((err) => console.log('error', err));
})
this does not trigger a download on the browser.
i am using react as front-end.
on the client i have a button triggering this upon click :
handleDownload() {
if (this.state.lastClicked) {
fetch("/api/topic/file/" + this.state.lastClicked._id)
.then(results => {
console.log('results', results)
return results;
})
} else {
//somthings...
}
}
Found a solution using downloadjs..
var download = require("downloadjs")
async handleDownload() {
const res = await fetch("/api/topic/file/" + this.state.lastClicked._id);
const blob = res.blob();
download(blob, this.state.lastClicked.name + '.docx');
}

How to render typescript file to javascript programmatically?

I'm trying to figure out how to render a typescript file programmatically to javascript file.
Is this possible to do with ts-node for example like this:
function tsMiddleware (req, res, next) {
var parsed = require('url').parse(req.url);
if (parsed.pathname.match(/\.ts$/)) {
return ts(parsed.pathname).then(function (o) {
res.setHeader('Content-Type', 'text/js');
res.end(o.js);
}).catch((err) => {
console.log(err);
});
}
next();
function ts(src) {
return new Promise((resolve, reject) => {
require('ts-node').render({
file: 'src' + src
}, function (err, res) {
if (err) {
reject(err);
} else {
resolve(res);
}
});
});
}
}
I don't want to execute the ts file in nodejs, but instead just compile ts file and send the output back to the browser.
Here is an example:
const ts = require("typescript")
async function tsTranspile(tsCode) {
return await ts.transpileModule(tsCode, { /* Here the compiler options */ })
}
How to use it:
tsTranspile("const f = a => a + 1")
.then(jsCode => console.log(jsCode))
.catch(err => console.log("Error:", err))
Read also:
Using the Compiler API;
Compiler Options.

TypeError: res.json is not a function when using require('fs');

Trying to pass contents for files I am reading via res.json. I think I am over writing my res function, but I dont see a fix.
app.get('/uploads/', (res, req) => {
dirname = './client/uploads'
fs.readdir(dirname, function(err, filenames) {
console.log(filenames)
if (err) {
console.log(err);
return;
}
filenames.forEach(function(filename) {
if (filename != '.DS_Store'){
fs.readFile(dirname + "/" + filename, 'utf-8', function(err, content) {
res.json({content: content})
if (err) {
//onError(err);
console.log(err)
return;
}
});
}
});
});
})
You mis-matched the arguments of /uploads route handler, req is the first argument
app.get('/uploads/', (req, res) => {
//...
})

Resources