2

I am streaming some data from my Node backend to a React frontend, and then am using the streamsaver library to take the stream and save it as a PDF. I was getting the correct number of documents downloaded at the end of the process. However, the pages are blank, suggesting the data is not being encoded properly. So I am trying to use base64 encoding.

My backend code looks like this:

  async getNotesPDFStream(args, session, ctx) {
    try {
      const data = await this.getDataToStream(args, session, ctx);
      fs.writeFileSync("./test.pdf", data); // This test works on the backend - creates a PDF
      const encodedData = btoa(data); // encoding as a base64 string
      const readable = new Readable();
      readable.push(encodedData);
      readable.push(null);
      readable.pipe(ctx.stream);
      return Response.Success("PDF now streaming!");
    } catch (err) {
      console.log("Error 167: ", err);
      return Response.Error("Error retrieving progress notes PDF.", err);
    }
  }

And on the React frontend I do this:

  let buffer = '';
   dataStream.on('data', (data) => {
     buffer += data;
  });

  dataStream.on('end', () => {
    console.log('STREAM FINISHED');
    const fileStream = streamSaver.createWriteStream('notes.pdf');

    const decodedData = atob(buffer); // Decode the final buffer
    console.log('decodedData: ', decodedData);

    const pdfBlob = new Blob([decodedData], { type: 'application/pdf' });
    const readableStream = pdfBlob.stream();

    if (window.WritableStream && readableStream.pipeTo) {
      return readableStream
        .pipeTo(fileStream)
        .then(() => console.log('Done writing'));
    }
    // Write (pipe) manually
    const writer = fileStream.getWriter();
    const reader = readableStream.getReader();
    const pump = () =>
      reader
        .read()
        .then(res =>
          res.done ? writer.close() : writer.write(res.value).then(pump)
        );
    pump();

After trying this I have the correct number of pages downloaded with the PDF document, but the pages are still blank. What am I missing here? How can I ensure this is encoded properly?

By the way, I tried using some basic html and passed that in the same way, using the same encoding methods, and it reconstructed the html correctly. Is there something specifically about constructing as a PDF that I need to be aware of?

1 Answer 1

1

In the end I realized I was making it more complicated than necessary. Using the writer.write() functionality I was able to come up with this terse working solution:

  dataStream.on('data', (data) => {
    writer.write(data) // should be a Uint8Array
  })

  dataStream.on('end', () => {
    console.log('STREAM FINISHED');
    writer.close();
  });
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.