Detailed description of issue
Hi Guys, I’m trying to embed this pdf viewer in a React App, but i’m getting this error when I try to change the path of the pdf inside the useEffect(), with a dynamic variable passed through props. The initial document on the first click is getting rendered correctly, but then if I try to click on another one I have this crash. I have tried to use instance.loadDocument(lib/pdf/${filePath}) but I’m getting an error: “pdf header error”. What shall I do here? Thanks for any help I will get
Expected behaviour
The pdf should change according to the filepath passed wihout any errors
Does your issue happen with every document, or just one?
Every document
You are remounting webviewer every time filePath changes which is bad practice and will make for a very slow application. I would recommend refactoring your code to something like this:
I have a problem with loading pdf file from parent props to child props. If i pass directly from parent props it will have TypeError: Object{…} is not a function. However if i pass through child state i will got an empty display.
Child Component:
import React, { Component, createElement, useState, useRef, useEffect } from "react";
import { WebViewer } from "@pdftron/pdfjs-express";
import "../ui/ReactPdfJs.css";
const PDFExpressCom = ({ getPath }) => {
const viewer = useRef(null);
const [currentPath, setCurrentPath] = useState(getPath);
alert("out 1: " + currentPath);
alert("out 2: " + getPath);
// if using a class, equivalent of componentDidMount
useEffect(() => {
if (getPath) {
setCurrentPath(getPath);
alert("inside if1: " + currentPath);
}
}, [currentPath, getPath]);
useEffect(() => {
if (getPath) {
setCurrentPath(getPath);
alert("inside if2: " + currentPath);
}
if (currentPath) {
alert("inside if3: " + currentPath);
WebViewer(
{
path: "/resources/public/webviewer/lib",
initialDoc: currentPath
},
viewer.current
).then(instance => {
alert("inside if3: " + currentPath);
const { docViewer, Annotations } = instance;
const annotManager = docViewer.getAnnotationManager();
docViewer.on("documentLoaded", () => {
const rectangleAnnot = new Annotations.RectangleAnnotation();
rectangleAnnot.PageNumber = 1;
// values are in page coordinates with (0, 0) in the top left
rectangleAnnot.X = 100;
rectangleAnnot.Y = 150;
rectangleAnnot.Width = 200;
rectangleAnnot.Height = 50;
rectangleAnnot.Author = annotManager.getCurrentUser();
annotManager.addAnnotation(rectangleAnnot);
// need to draw the annotation otherwise it won't show up until the page is refreshed
annotManager.redrawAnnotation(rectangleAnnot);
});
});
alert("inside if4: " + currentPath);
}
}, [getPath]);
return (
<div className="App">
<div className="header">Digital Document</div>
<div className="webviewer" ref={viewer}></div>
</div>
);
};
export default PDFExpressCom;
You are remounting webviewer every single time path changes which is probably not what you want to do. Instead, use the loadDocument API to load the new path.
So your child component could look something like this instead:
What if there is no initial doc? Specifically, I load a pdf document as soon as there is a response (with file buffer) for a request. How can I fix the 2 instance issue in this case?