pdfpdftronpdf-form

PDFTron full api is not getting loaded in WebViewer


I am trying to get the full api of PDFTron working from the WEbViewer. I followed the steps in the link below. https://www.pdftron.com/documentation/web/guides/full-api/setup/

But I am getting the error given below in console while loading the webviewer.

Uncaught (in promise) Error: Full version of PDFNetJS has not been loaded. Please pass the "fullAPI: true" option in your WebViewer constructor to use the PDFNet APIs.
    at Object.get (CoreControls.js:1694)
    at z.docViewer.on ((index):43)
    at CoreControls.js:398
    at Array.forEach (<anonymous>)
    at z.O (CoreControls.js:398)
    at CoreControls.js:213

enter image description here

enter image description here

This is my code.

         WebViewer({
        path: 'WebViewer-6.0.2/lib', // path to the PDFTron 'lib' folder on your server
        type: 'html5',
         initialDoc: 'forms/local.pdf',  // You can also use documents on your server
         fullAPI: true,
      }, document.getElementById('viewer'))
      .then(instance => {
        const docViewer = instance.docViewer;
        const annotManager = instance.annotManager;

    const Annotations = instance.Annotations;
    Annotations.ChoiceWidgetAnnotation.FORCE_SELECT=true;
    const Actions = instance.Actions;
      docViewer.on('documentLoaded', async () => {
      const  PDFNet = instance.PDFNet;
      await PDFNet.Initialize();
      // This part requires the full API: https://www.pdftron.com/documentation/web/guides/full-api/setup/
      alert('async');
      const doc = docViewer.getDocument();
      // Get document from worker
      const pdfDoc = await doc.getPDFDoc();
      pdfDoc.getAcroForm().putBool("NeedAppearances", true);
      });
    docViewer.on('documentLoaded', () => {
 docViewer.on('annotationsLoaded', () => {
      const annotations = annotManager.getAnnotationsList();
      annotations.forEach(annot => {
      console.log('fieldName => '+annot.fieldName);

});
    });

Please help me resolve this.

EDIT

Modified the code as suggested by @Andy. The updated code in index.html file looks like below,

    <!DOCTYPE html>
<html>
<head>
  <title>Basic WebViewer</title>
</head>

<!-- Import WebViewer as a script tag -->
<script src='WebViewer-6.0.2/lib/webviewer.min.js'></script>


<body>
  <div id='viewer' style='width: 1024px; height: 600px; margin: 0 auto;'>
  <script>
  WebViewer({
    path: 'WebViewer-6.0.2/lib', // path to the PDFTron 'lib' folder on your server
    type: 'html5',
     fullAPI: true,
     // licenseKey: 'Insert commercial license key here after purchase',
  }, document.getElementById('viewer'))
  .then(async instance => {
  const { Annotations, Tools, CoreControls, PDFNet, PartRetrievers, docViewer, annotManager } = instance;
    await PDFNet.Initialize();
        Annotations.ChoiceWidgetAnnotation.FORCE_SELECT=true;
    const Actions = instance.Actions;
      docViewer.on('documentLoaded', async () => {
      // This part requires the full API: https://www.pdftron.com/documentation/web/guides/full-api/setup/
      const doc = docViewer.getDocument();
      // Get document from worker
      const pdfDoc = await doc.getPDFDoc();
      const acroFrom = await pdfDoc.getAcroForm();
      acroform.putBool("NeedAppearances", true);
      });
    instance.loadDocument('forms/test.pdf');
  });
</script>
  </div>
</body>
</html>

I am loading the file from a http server in my project folder.

 http-server -a localhost -p 7080

Unfortunately, I am getting the same error.

Error: Full version of PDFNetJS has not been loaded. Please pass the "fullAPI: true" option in your WebViewer constructor to use the PDFNet APIs.

enter image description here

We are currently evaluating PDFTron, so the licenseKey option is not passed in the WebViewer constructor.

Kindly help me on this.


Solution

  • I have tried out the code you have provided and was still not able to reproduce the issue you are encountering. I do typically perform the initialize outside WebViewer events so the initialization occurs only once:

    WebViewer(...)
        .then(instance => {
            const { Annotations, Tools, CoreControls, PDFNet, PartRetrievers, docViewer } = instance;
            const annotManager = docViewer.getAnnotationManager();
    
            await PDFNet.initialize(); // Only needs to be initialized once
    
            docViewer.on('documentLoaded', ...);
            docViewer.on('annotationsLoaded', ...);
    });
    

    Also, I noticed that you attach an an event handler to annotationsLoaded every time documentLoaded is triggered. I am not sure if that is intentional or desirable but this can lead to the handler triggering multiple times (when switching documents).

    This may not matter but instead of using initialDoc, you could try instance.loadDocument after the initialize instead.

    await PDFNet.initialize();
    
    docViewer.on('documentLoaded', ...);
    docViewer.on('annotationsLoaded', ...);
    
    instance.loadDocument('http://...');
    

    There is one last thing to mention about the full API. The APIs will return a promise most of the time as the result so you will have to await the return value most of the time.

    const acroFrom = await pdfDoc.getAcroForm();
    // You can await this too. Especially if you need a reference to the new bool object that was
    acroform.putBool("NeedAppearances", true);
    

    Let me know if this helps!