Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Error: stream.push() after EOF in react-pdf

Im trying to open a pdf document using react-pdf

const PDFDocument = () => {

  const [PDFData, setPDFData] = useState(() => {
    const data = localStorage.getItem('pdfData')
    return JSON.parse(data)
  })

  useEffect(() => {
    console.log(PDFData)
  }, [PDFData])

  const { NameOfService, AccessibilityDetails, AddressLine1, AddressLine2, AddressLine3, Postcode, OtherDetailedInformation, MondayStart, MondayEnd, TuesdayStart, TuesdayEnd, WednesdayStart, WednesdayEnd, ThursdayStart, ThursdayEnd, FridayStart, FridayEnd, SaturdayStart, SaturdayEnd, SundayStart, SundayEnd, Cost,  Buses, TubeAndTrains, CarParkingDetails, Name1, PhoneNumber1, Email1, Name2, PhoneNumber2, Email2, Website, OtherContactInfo  } = PDFData

  return (
    <PDFViewer>
      <Document>
        <Page size="A4" style={styles.page}>
          <View style={styles.heading}>
            <Text>{NameOfService}</Text>
          </View>
          <View style={styles.text}>
            <Text>{AddressLine1}</Text>
            <Text>{AddressLine2}</Text>
            <Text>{AddressLine3}</Text>
            <Text>{Postcode}</Text>
          </View>
          <View style={styles.text}>
            <Text>{OtherDetailedInformation}</Text>
          </View>
          <View style={styles.text}>
            {MondayStart ? <Text>Monday: {MondayStart} - {MondayEnd}</Text> : null}
            {TuesdayStart ? <Text>Tuesday: {TuesdayStart} - {TuesdayEnd}</Text> : null}
            {WednesdayStart ? <Text>Wednesday: {WednesdayStart} - {WednesdayEnd}</Text> : null}
            {ThursdayStart ? <Text>Thursday: {ThursdayStart} - {ThursdayEnd}</Text> : null}
            {FridayStart ? <Text>Friday: {FridayStart} - {FridayEnd}</Text> : null}
            {SaturdayStart ? <Text>Saturday: {SaturdayStart} - {SaturdayEnd}</Text> : null}
            {SundayStart ? <Text>Sunday: {SundayStart} - {SundayEnd}</Text> : null}
          </View>
          <View style={styles.text}>
            <Text>Cost: {Cost}</Text>
          </View>
          <View style={styles.text}>
            <Text>Transport:</Text>
            <Text>Buses: {Buses}</Text>
            <Text>Tube and Trains: {TubeAndTrains}</Text>
            <Text>Car park Availibility: {CarParkingDetails}</Text>
          </View>
          <View style={styles.text}>
            {AccessibilityDetails ? <Text>Accessibility: {AccessibilityDetails}</Text> : null}
          </View>
          <View style={styles.text}>
            <Text>Contact Details:</Text>
            <Text>{Name1}: {PhoneNumber1}; {Email1}</Text>
            {Name2 ? <Text>{Name2}: {PhoneNumber2}; {Email2}</Text> : null}
          </View>
          <View style={styles.text}>
            {Website ? <Text>{Website}</Text> : null}
          </View>
          <View style={styles.text}>
            {OtherContactInfo ? <Text>{OtherContactInfo}</Text> : null}
          </View>
        </Page>
      </Document>
    </PDFViewer>
  )
};

export default PDFDocument;

The localstorage data is set in the App component when ever someone click a 'print' button.

handlePrint = (pdfData) => {
    localStorage.setItem('pdfData', JSON.stringify(pdfData))
  }

The pdf opens on in a new tab using react-router

<Route path="/pdf" render={ () => <PDFDocument/> } />

The tab opens with the pdf but with no data, two pages, and the error in the console stream.push() after EOF in react-pdf

Live site the pdf won't open.

like image 667
Chris Carr Avatar asked Oct 08 '19 18:10

Chris Carr


1 Answers

I just got this to work today and I was having the same EOF error and two blank pages. I think the problem is that the PDF renderer or the document has not fully loaded / generated so you need to call a function to actually generate the pdf first, than once that function is complete display the PDF Viewer to either view or get the document this is what I did to fix:

import React from 'react';
import { Button } from 'react-bootstrap';
import { Text, Image, View, Page, Document, PDFDownloadLink } from '@react-pdf/renderer';

import './App.css';

export default class App extends React.Component {
    constructor() {
        super();

        this.state = {
            ready: false
        }
    }

    toggle() {
        this.setState((prevState) => ({
            ready: false
        }), () => {     // THIS IS THE HACK
            setTimeout(() => {
                this.setState({ ready: true });
            }, 1);
        });
    }

    render() {
        const { ready } = this.state;

        const MyDocument = (
            <Document>
                <Page size="A4">
                    <View>
                        <Text>
                            some text
                        </Text>
                    </View>
                </Page>
            </Document>
        );

        return (
            <div>
                {ready && (
                    <PDFDownloadLink document={MyDocument} fileName="PDF">
                        {
                            ({ blob, url, loading, error }) => (loading ? 'Loading document...' :
                                <Button onClick={() => (this.setState({ ready: false }))}>
                                    download pdf
                                </Button>
                            )
                        }
                    </PDFDownloadLink>
                  )}
                {!ready && (
                   <Button onClick={() => this.toggle()}>
                        generate pdf
                    </Button>
                )}
            </div>
        );
    }
}
like image 183
bleepbloopblop123 Avatar answered Oct 05 '22 18:10

bleepbloopblop123