1

I'm trying to create a Vue.js (Quasar) project, and I have a problem with pdf.js when tries to run .getPage function. Here is my code

<template>
  <div>
    <canvas ref="canvas" height="100%" width=100%></canvas>
  </div>
</template>

<script>
import * as pdfjsLib from 'pdfjs-dist/build/pdf';

pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdnjs.cloudflare.com/ajax/libs/pdf.js/3.4.120/pdf.worker.min.js';

export default {
  data() {
    return {
      pdf: null,
      currentPage: 1,
      numPages: 0,
      rendering: false,
      pageRenderingQueue: []
    };
  },
  props: {
    src: {
      type: String,
      required: true
    },
    pagesPerRender: {
      type: Number,
      default: 1
    },
    scale: {
      type: Number,
      default: 1
    }
  },
  mounted() {
    this.loadPdf();
  },
  methods: {
    async loadPdf() {
      let loadingTask = pdfjsLib.getDocument(this.src);
      loadingTask.promise.then(pdf =>{
        console.log("pdf ", pdf);
        this.pdf = pdf;
        this.numPages = pdf.numPages;
        this.renderPages();
      }).catch(error => {
        console.error('Failed to load PDF:', error);
      });
    },
    async renderPages() {
      if (this.rendering) {
        return;
      }

      this.rendering = true;
      const pagesToRender = [];
      for (let i = this.currentPage; i < Math.min(this.currentPage + this.pagesPerRender, this.numPages + 1); i++) {
        pagesToRender.push(i);
      }
      
      for (let i = 0; i < pagesToRender.length; i++) {
        const pageNumber = pagesToRender[i];
        if (this.pageRenderingQueue.includes(pageNumber)) {
          continue;
        }

        this.pageRenderingQueue.push(pageNumber);
        this.pdf.getPage(pageNumber).then((page) =>{
          this.handlePage(page);
        });
      }
    },
    handlePage(page){
      const viewport = page.getViewport({ scale: this.scale });
      const canvas = this.$refs.canvas;
      const context = canvas.getContext('2d');
      canvas.width = viewport.width;
      canvas.height = viewport.height;
      const renderContext = {
        canvasContext: context,
        viewport: viewport
      };

      const renderTask = page.render(renderContext);
      renderTask.then(() => {
        console.log("render task completed succesfully")
        const index = this.pageRenderingQueue.indexOf(pageNumber);
        this.pageRenderingQueue.splice(index, 1);
        if (this.pageRenderingQueue.length === 0) {
          this.rendering = false;
        }
      });
    }
  }
};
</script>

and the error

Uncaught (in promise) TypeError: Cannot read private member #pagePromises from an object whose class did not declare it
    at Proxy.getPage (pdf.js?6178:2375:1)
    at Proxy.getPage (pdf.js?6178:1215:1)
    at Proxy.renderPages (PdfViewer.vue?772b:69:1)
    at eval (PdfViewer.vue?772b:46:1)

I'm using the package version 3.4.120 (installed via npm)

I tried to use this url '//mozilla.github.io/pdf.js/build/pdf.worker.js' in pdfjsLib.GlobalWorkerOptions.workerSrc, as of this example https://mozilla.github.io/pdf.js/examples/, but it points out to a version 3.5.97, and a mismatch occurs.

vitzi
  • 21
  • 3
  • It's likely because class instance shouldn't be transformed to be reactive. Don't use `pdf` in `data`. See https://stackoverflow.com/questions/54906710/vuejs-disable-reactivity-for-specific-properties – Estus Flask Mar 24 '23 at 05:20

1 Answers1

0
let pdf = null

// ...

loadingTask.promise.then(pdf =>{
    pdf = pdf;
})


// ...

pdf.getPage()