Esto probablemente se deba a mi experiencia limitada con JavaScript, pero no he podido resolver esto. Este es un proyecto Vue 2 + Typescript, pero el problema específico no tiene nada que ver con Vue o Typescript.
ESTÁ BIEN. Así que he agregado las siguientes funciones en uno de mis componentes. El objetivo principal de este componente es tomar un archivo PDF y devolver la versión rasterizada de su primera página en forma de Blob . Aquí están mis funciones:
async importButtonHandler () { if (this.file) { const blob = await this.pdfToBlob(this.file) if (blob) { const file2 = new File([blob], 'raster_pdf', { type: 'image/png' }) // Further processing } } } async pdfToBlob (pdfFile: File): Promise<Blob|null> { const canvas: HTMLCanvasElement = document.createElement('canvas') const buffer = await this.readFileAsync(pdfFile) const typedarray = new Uint8Array(buffer) // get handle of pdf document const doc = await pdfjsLib.getDocument(typedarray).promise // get handle of page const pdfpage = await doc.getPage(1) // get viewport to render the page at required scale const viewport = pdfpage.getViewport() // set canvas height same as viewport height canvas.height = viewport.height canvas.width = viewport.width const renderContext: RenderParameters = { canvasContext: canvas.getContext('2d') as CanvasRenderingContext2D, viewport: viewport } // render the page contents in the canvas await pdfpage.render(renderContext).promise return new Promise((resolve, reject) => { try { canvas.toBlob(resolve) } catch (error) { reject(error) } }) } readFileAsync (file: File): Promise<ArrayBuffer> { return new Promise((resolve, reject) => { const reader = new FileReader() reader.onload = () => { resolve(reader.result as ArrayBuffer) } reader.onerror = reject reader.readAsArrayBuffer(file) }) } Accede a la función pdfToBlob y llama a readFileAsync desde allí, lee el archivo en el buffer correctamente, pero inmediatamente después (en const typedarray = new Uint8Array(buffer) ) en lugar de ejecutar esa línea, vuelve a activar la función pdfToBlob y luego lanza una excepción que dice :
TypeError: Cannot read properties of undefined (reading 'getDocument')
y por mi vida, no puedo entender por qué ingresa la función nuevamente (no hay otro lugar donde se llame a esta función).
Mi instinto es que se trata de la Promesa que estoy regresando en la función, pero toda mi experimentación no me ha llevado a ninguna pista.
¿Puede alguien ayudarme a averiguar qué está mal aquí?
Lo descubrí (más o menos).
En primer lugar, mi pdfjsLib debía importarse correctamente y proporcionarse un trabajador antes de llamar a getDocument . Esta fue la causa de mi segundo problema. Esta es la forma correcta de importar la biblioteca y el trabajador en el proyecto Vue 2/Typescript:
import * as pdfjsLib from 'pdfjs-dist' import pdfjsWorker from 'pdfjs-dist/build/pdf.worker.entry'Luego suministre trabajador a la biblioteca y llame a getDocument:
pdfjsLib.GlobalWorkerOptions.workerSrc = pdfjsWorker const doc = await pdfjsLib.getDocument(YOUR_PDF_DATA).promise El resto del código en mi OP funciona correctamente. Tenga en cuenta que pdf.worker.entry no tiene definiciones de tipo (o al menos no pude encontrarlas en ninguna parte), pero funciona de todos modos.
El primer problema de llamar al controlador varias veces parece ser un problema conocido (o un comportamiento, si lo prefiere) en Vuetify. Sugieren usar native o prevent o stop al definir el atributo de click (como @click.stop="importButtonHandler" ) para mitigar el comportamiento. Lo he probado sin éxito. Mi controlador todavía se llama dos veces. En mi escenario particular, esto no causa ningún daño funcional, por lo que puedo vivir con eso por ahora, pero puedo pensar en situaciones en las que este comportamiento podría ser desastroso.
Espero que esto ayude a alguien en el camino.