Search code examples
javascriptgoogle-cloud-functionspdfmake

How to return a value from inside of an event that is located inside the main function?


I'm creating a function in Google Cloud functions that should return a base64 pdf. I'm using the pdfmake library. With a console.log() I can see that the base64 is generated correctly, but I'm unable to return the value to the caller.

The pdf doc is closed with .end(), and that triggers the event .on('end'). The problem is that I can't seem to return the value from inside the event.

When I put the return inside the event (as it is right now), firebase waits out and return a null.

If I put the return after the .end(), the value returned is null, as if the event was async and did't have any time to proccess.

exports.pdf = functions.https.onCall((data, context) => {

    var PdfPrinter = require('pdfmake');
    var printer = new PdfPrinter(fonts);

    let fonts = {...};
    var docDefinition = {...};

    var pdfDoc = printer.createPdfKitDocument(docDefinition);

    let chunks = [];
    let pdfBase64 = null;

    pdfDoc.on('data', (chunk) => {
        chunks.push(chunk);
    });        

    pdfDoc.on('end', () => {
        const result = Buffer.concat(chunks);
        pdfBase64 = 'data:application/pdf;base64,' + result.toString('base64');
        console.log(pdfBase64);
        return {pdfBase64: pdfBase64};
    });


    pdfDoc.end();



});

How could I return the value?


Solution

  • You need to return a promise that eventually resolves with the data to send to the client. Try something like this:

    // everything above stays the same
    
    const p = new Promise((resolve, reject) => {
        pdfDoc.on('end', () => {
            const result = Buffer.concat(chunks);
            pdfBase64 = 'data:application/pdf;base64,' + result.toString('base64');
            console.log(pdfBase64);
            resolve({pdfBase64: pdfBase64});
        });
    })
    
    pdfDoc.end();
    
    return p;