0

I'm currently trying to generate a PDF with puppeteer, then render a page with a "thank you" message to the user. Once the user hits that page, the Puppeteer PDF will hopefully begin downloading on the user's machine. But I'm having some troubles.

I can successfully redirect the user to the page I want them on after collecting some basic info from a form:

app.post("/generatepdf", function (req, res) {

  UserPdfRequest.create({ email: req.body.email, companyName: req.body.companyName }, function (err, createdRequest) {
    if (err) {
      console.log(err);
    } else {
      console.log(createdRequest);
      res.redirect("/" + createdRequest._id + "/pdf-download");
    }
  })

});

Then, I send them to my route which handles finding the user in question, generating the PDF, then rendering the Thank You page:

app.get("/:companyId/pdf-download", function (req, res) {

  UserPdfRequest.findById(req.params.companyId, function (err, foundRequest) {
    if (err) {
      console.log(err);
    } else {
      console.log(foundRequest);

      (async () => {
        const browser = await puppeteer.launch()
        const page = await browser.newPage()
        const url = 'http://localhost:3000/' + req.params.companyId + '/pdf-download';
        await page.goto(url, {waitUntil: 'networkidle0'});
        const buffer = await page.pdf({ format: "A4", printBackground: true });
        res.type('application/pdf')
        res.send(buffer)
        browser.close()
      })()

      res.render("pdfDownload", { email: foundRequest.email, companyName: foundRequest.companyName });
    }
  })

});

But when I land on the Thank You page, my PDF does not begin downloading. Furthermore, my console.log(foundRequest) seems to log over and over again very rapidly in my terminal, and I also receive the following errors:

https://i.stack.imgur.com/n4RtC.jpg

I know I'm probably in over my head here given I don't have much experience with async. I'm sure this is a simple fix I'm missing; however, any help (and explanation) would be extremely valuable and appreciated. Thank you for your time!

Aaron Marsden
  • 345
  • 3
  • 12

1 Answers1

0

You are calling send and render on the same response object. You can either send the data or send html but you cannot do it for the same request. Usually it is workarounded by opening a new tab for downloading.

Shlang
  • 2,495
  • 16
  • 24
  • Thanks for the comment. Do you think it would be better to add another route for the PDF generation, then call that route in Javascript with an AJAX call once the page loads? Or connect it to a button. That's what I'm thinking at the moment, but I'd love extra thoughts. – Aaron Marsden Mar 07 '20 at 01:18
  • Sending AJAX means you need to handle it on client side – you'll need to implement something like described [here](https://stackoverflow.com/questions/4545311/download-a-file-by-jquery-ajax). Opening a new tab can be done just by adding `target="_blank"` to the form, but some code is still needed in order to achieve your second requirement – change the page after the form submit. – Shlang Mar 07 '20 at 11:10