Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

File responsed by response.download() and download as blob containing undefined

I’m building a client-server certificate generator.


On Backend
I’m using two endpoints:

/
  • Receives a JSON containing data extracted from inputs, sanitize them, and returns if they’re valid or not
/download
  • Receives whether data is valid or not. If it’s, generate a certificate.pdf file and responses it with res.download(certificatePath)
  • I guess I should use some kind of token/authentication/authorization because someone could just ignore the first endpoint but I’ll do that once the downloading itself is fixed

I think the problem with backend is in some of those functions:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

const getCertificatePDF = (name, validValuesData, validValuesQty, response) => {
    // ... ommited for brevity
    pdf.create(document, options)
        .then(res => {
            console.log(res)
            let filePath = path.join(__dirname, 'certificate.pdf');
            console.log("FILE PATH: ", filePath);                            
            response.download(filePath, "certificate.pdf");
        })
        .catch(error => {
            console.error(error)
        });
}

app.post('/download', (req, res) => {
    const data = req.body;
    console.log("DATA", data);
    getCertificatePDF(data.name, data.validValuesData, data.validValuesQty, res)
});

On frontend, I chained both requisitions using promises, created a blob, created a link with download attribute for that blob and triggered anonClick:

const sendForm = (filledCodeValues, email, name) =>{
    // ...ommited for brevity

    fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: data,
      })
        .then((res) => res.json())
        .then((processedData) => {
            alertAllFilledInvalid(processedData.validValuesQty)
            const dataString = JSON.stringify(processedData);
            if(processedData.validValuesQty > 0){
                console.log("DATA STRING ", dataString)
                const downloadUrl = url + "download";
                fetch(downloadUrl, {
                    method: "POST",
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: dataString,
                  })
                .then((res2) => {
                    res2.blob()
                })
                .then((blob)=>{
                    const newBlob = new Blob([blob]);
                    const newUrl = window.URL.createObjectURL(newBlob);

                    const link = document.createElement('a');
                    link.href = newUrl;
                    link.setAttribute('download', 'certificate.pdf');
                    document.body.appendChild(link);
                    link.click();
                    link.parentNode.removeChild(link);

                    window.URL.revokeObjectURL(newBlob);
                })
            }
        })
}

Issue

The issue is, the certificate.pdf downloaded by frontend is containing undefined:
undefined certificate downloaded by frontend

I know the first request is correct, because the console.log() is printing the expected contents for stringData:

frontend manages to complete first request

I also know the second request work, because on backend, certificate.pdf is being correctly generated:

Backend receives second requisition correctly and generated pdf

Ps – i’m manually deleting certificate.pdf on backend to ensure it’s a new one generated

Since certificate is being generated, I believe there’s something wrong with either:

  1. Backend’sresponse.download(filePath, "certificate.pdf");
  2. FrontEnd blob creating and downloading

I manually moved certificate(25).pdf (generated by frontend) to backend and run a script for reading both certificate.pdf(generated by backend) files, to test if the issue is on filePath using a readFiles.js script:

const fs = require('fs');
let path = require('path');

let filePath = path.join(__dirname, 'certificate.pdf');
console.log("FILE PATH: ", filePath);
fs.readFile(filePath, 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(">>>>> FilePath content <<<<< ", data);
});


let filePath2 = path.join(__dirname, 'certificate(25).pdf');
console.log("FILE PATH 2: ", filePath2);
fs.readFile(filePath2, 'utf8', (err, data) => {
    if (err) {
        console.error(err);
        return;
    }
    console.log(">>>> FilePath2 content <<<< ", data);
});

readFiles

It turns out the path is correct, and certificate.pdf (backend) has content, while certificate(25).pdf (frontend) has just an undefined value.


Can someone help me please?

>Solution :

You need to return the value of res2.blob():

.then((res2) => {
  return res2.blob()
})

Or leave out the brackets:

.then((res2) => res2.blob())
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading