2

I have code that just downloads a file that exists in my backend. I can see the pdf on the backend is created properly and in the right place, but when I send and download the file to the frontend and open it I get the error "Failed to load pdf document" no matter which browser I use. I think this must mean there is something wrong with my blob downloading code since I can open and see the file on the backend, but I can't figure it out. I have tried following many examples online and I get the same issue regardless of what I have tried.

server.js (node backend file)

app.get('/api/v1/getPdf', function(req, res) {
  let resolve = require('path').resolve
  res.sendFile(resolve('./tickets/tickets.pdf'));
});

PrintDetails.js (React js code for downloading pdf) - Note: I only included the relevant parts

class PrintDetails extends React.Component {

async printTickets() {
      let file = await getTicketsPdf();
      console.log(file);
      const blob = new Blob([file], {type: 'application/pdf'});
      const link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = 'tickets.pdf';
      document.body.appendChild(link);
      link.click();

      setTimeout(function() {
        document.body.removeChild(link);
    }, 100);
  }

render() {
    return (
        <div>
            <button className="download-button-icon" onClick={this.printTickets}>Download</button>
        </div>
    )
}

  async function getTicketsPdf() {
    let data = {};
    await (async () => {
      const rawResponse = await fetch('/api/v1/getPdf', {
        method: 'get',
        headers: {
          'responseType': 'blob',
          'Content-Type': 'application/json'
        },
      });
      data = await rawResponse;
    })();
  
    return data;
  }

1 Answers1

7

Here's my implementation using axios and file-saver.

Node.js backend

app.get('/api/v1/getPdf', function(req, res) {
  res.download('./tickets/tickets.pdf');
});

React frontend

import { saveAs } from 'file-saver'
.
.
.
async function printTickets() {
  const { data } = await getTicketsPdf()
  const blob = new Blob([data], { type: 'application/pdf' })
  saveAs(blob, "tickets.pdf")
}

async function getTicketsPdf() {
  return axios.get('/api/v1/getPdf', {
    headers: {
      'Content-Type': 'multipart/form-data'
    },
    responseType: 'arraybuffer'
  })
}
kausko
  • 930
  • 3
  • 10
  • That seemed to work thanks! I am not sure what ended up being the issue, but this did what I needed it to. Thanks again! – Mackenzie Quigley May 15 '21 at 15:59
  • @MackenzieQuigley I'm glad I could help. The issue could've been happening because of the response and/or content type. I'm not sure about that too. – kausko May 15 '21 at 20:16