I can't seem to deinstance the webviewer component

WebViewer Version: 6.14.16

Please give a brief summary of your issue:

I can’t remove the webviewer from the page when I’m done with it.

Please describe your issue and provide steps to reproduce it:

I’m trying to use the webviewer in a React application. I have a section of the code where there is a ternary operator that determines whether a list of pdf files is displayed or the webviewer when the user clicks on one of the files. I’m trying to deinstance the webviewer with UI.dispose() when the user is done with the file and goes back to the file list. dispose() closes the file that is open, but the iframe remains visible in the code, even though it’s in the wrong expression of the ternary operator. In addition to that, whenever the user comes back from that view, an additional iframe is displayed.

I think I can see why it’s showing in the wrong expression, it seems to be going by the element index rather than by any kind of identifier. In both cases it’s being inserted into the second child of the top parent of the expression.

What I can’t figure out is how to get rid of the iframe entirely until I’m ready to use it again.

    const viewerDiv = useRef<HTMLDivElement | null>(null)
    const [viewerInstance, setViewerInstance] = useState<WebViewerInstance | undefined>()

    const documentPath = () => {
        return documentURL + selectedMedDocumentIndex + "/file?userid=" + userId
    }

    useEffect(() => { 
        if (showRecordGrid){
            if (viewerInstance){
                viewerInstance?.UI.dispose();
                viewerDiv.current = null;

                setViewerInstance(undefined);
            }
        }else{
            if (selectedMedDocumentIndex) {
                WebViewer({
                    path: 'lib/pdftron',
                    initialDoc: documentPath()
                }, viewerDiv.current as HTMLDivElement).then(instance => {
                    instance.Core.documentViewer.addEventListener('documentLoaded', () => {
                        instance.UI.openElements(['leftPanel'])
                    });
                    setViewerInstance(instance);
                });
            }
        }

    }, [showRecordGrid])
	
	return (
	...
	
	showRecordGrid ?
		<div className='tab-records'>
			<div className='refresh-button-container'>
				...
			</div>
			<div className='aux-document-container record-container'>
				<!--after webviewer is created for the first time and showRecordGrid is set back to true, webviewer is displaying here. Additional iframes are created every time the user comes back from this view-->
				...
			</div>
			...
		</div> :
		<div className='viewer-files-list-outer' >
			<div className="viewer-files-list">
				...
			</div>
			
			<div className='webviewer' ref={viewerDiv}></div> <!--when showRecordGrid is false, webviewer displays here with no problem, like it's supposed to-->
		</div>
            
	
	...
	)

Hello, I’m Ron, an automated tech support bot :robot:

While you wait for one of our customer support representatives to get back to you, please check out some of these documentation pages:

Guides:APIs:Forums:

Hello MarkP,

Welcome to the PDFTron Community Forum!

Have you tried the dispose() function on the WebViewer instance as well as the UI?

instance.UI.dispose()
instance.dispose()

An alternative would be conditionally rendering WebViewer, by checking if you want to render WebViewer and returning a component if true, something like

return {
   ... code ...
  {shouldShowViewer && <div className='webviewer' ref={viewerDiv}></div> }
}

Let me know if either work for you!

Best regards,
Tyler Gordon
Web Development Support Engineer
PDFTron

instance.dispose() gets me this error

Property 'dispose' does not exist on type 'WebViewerInstance'.

The second suggestion didn’t help either. I’m already not displaying the entire block of code that the webviewer element is contained in, and the webviewer is still showing up. Adding another condition for that one element didn’t do anything different.

Apparently we have to remove the element from the DOM manually.

I ended up putting the webviewer and associated code in its own component and calling it from the component I wanted to put it in. That seemed to do the trick. React took care of removing unneeded things from the DOM for me.