In remix react html to pdf generation getting error Warning: React.jsx: type is invalid -- expected a string

28 views Asked by At

PdfDocument.js file

import ReactPDF, { Page, Document, Image, StyleSheet, Text, View, renderToStream } from '@react-pdf/renderer';

import ReactDOMServer, { renderToStaticMarkup } from 'react-dom/server';
import Html from 'react-pdf-html';

export default function PdfDocument(props) {

  console.log('props', props)

  const element = (
    
        <><style>
      {`
      table {
        border: 1px solid #ccc;
        borderCollapse: collapse;
        margin: 0;
        padding: 0;
        width: 100%;
        tableLayout: fixed;
      }
      
      table caption {
        font-size: 1.5em;
        margin: .5em 0 .75em;
      }
      
      table tr {
        border: 1px solid #ddd;
        padding: .35em;
        border: 1px solid #ccc;
      }
      table th{
        background-color: #f8f8f8;
      }
      table th,
      table td {
        padding: .625em;
        text-align: center;
        border: 1px solid #ccc;
      }
      
      table th {
        font-size: .85em;
        letter-spacing: .1em;
        text-transform: uppercase;
      }
    `}
    </style><table>
        <thead>
          <tr>
            <th scope="col">Date</th>
            <th scope="col">Headline</th>
            <th scope="col">Publication</th>
            <th scope="col">Edition</th>
            <th scope="col">Page No.</th>
            <th scope="col">Journalist</th>
            <th scope="col">MAV</th>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td colSpan={6}> Financial</td>
          </tr>
          <tr>
            <td data-label="date">04/01/2016</td>
            <td data-label="headline">
              Deals warm up, hint funding spring near
            </td>
            <td data-label="publication">Mint Mint</td>
            <td data-label="edition">New Delhi</td>

            <td data-label="pageno">1,6</td>
            <td data-label="journalist">Munishwaran m</td>
            <td data-label="mav">12123</td>
          </tr>
        </tbody>
      </table></>
      
  );
      
  const htmls = renderToStaticMarkup(element);

  return (
    <Document>
      <Page>
        <Html>{htmls}</Html>
      </Page>
    </Document>
  );

 }

test-pdf.jsx

import { ActionFunctionArgs, LoaderFunction, LoaderFunctionArgs, json } from '@remix-run/node';
import { useActionData, useFetcher } from '@remix-run/react';
import { useState, useEffect } from 'react';
import PdfDocument from '~/utils/pdf.server';
import * as FileSaver from 'file-saver';
import { PDFDownloadLink, Document, Page, renderToStream } from '@react-pdf/renderer';

export default function Pdf() {
  // const userDetails = useFetcher<typeof loader>();
  const [showDetails, setShowDetails] = useState(false);
  const actionData = useActionData<typeof action>();
  const fetcher = useFetcher();


  const fileType = 'application/pdf';
  const fileExtension = '.pdf';
 
  useEffect(() => {
    if (showDetails) {
      setShowDetails(false)
      const myHeaders = new Headers();
      myHeaders.append("Content-Type", "application/json");

      const requestOptions = {
        method: "POST",
        headers: myHeaders,
        body: JSON.stringify({}),
        redirect: "follow"
      };

      fetch("test-pdf?_data=routes%2Ftest-pdf", requestOptions)
        .then((response) => response.blob())
        .then((result) => {
          console.log(result)
          const data = new Blob([result], { type: fileType });
          FileSaver.saveAs(data, 'fileName' + fileExtension);
        })
        .catch((error) => console.error(error));


    }
  }, [showDetails]);


  return (
    <>
      <button
        onClick={() => setShowDetails(true)}
      >
        submit
      </button>
    </>
  );
}

export const action = async ({
  request }: ActionFunctionArgs) => {
  switch (request.method) {
    case "POST": {
      const req = await request.json()
      // const stream = await PdfDocument(req);
      // console.log('PdfDocument', <PdfDocument></PdfDocument>)
      let stream = await renderToStream(<PdfDocument data={req}></PdfDocument>);
      // and transform it to a Buffer to send in the Response
      const body: Buffer = await new Promise((resolve, reject) => {
        let buffers: Uint8Array[] = [];
        stream.on("data", (data) => {
          buffers.push(data);
        });
        stream.on("end", () => {
          // resolve(Buffer.concat(buffers).toString('utf-8'));
          resolve(Buffer.concat(buffers));
        });
        stream.on("error", reject);
      });
    }
  }
  return json({ message: "Method not allowed" }, 405);
};

i tried html element pass getting error Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object.

Error: Minified React error #130; visit https://reactjs.org/docs/error-decoder.html?invariant=130&args[]=object&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.

I'm passing html element getting error of type is invalid

0

There are 0 answers