lennin92
lennin92

Reputation: 513

pdfmake.js Uncaught TypeError: Cannot read property 'length' of null

Uncaught TypeError: Cannot read property 'length' of null

when running the next html/javascript code on my client machine, but it works on playground, but i dont know what the error is.

PLAYGROUND: http://pdfmake.org/playground.html

<html> <head>
<title>Ingreso Simple</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.20/pdfmake.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.20/vfs_fonts.js"></script>
</head> <body> <script>
var usuario = 'user';
var left = 25;
var right = 25;
var top = 290;
var bottom = 50;


var dd = {
    // a string or { width: number, height: number }
    pageSize: 'LETTER',

    // by default we use portrait, you can change it to landscape if you wish
    pageOrientation: 'portrait',

    // [left, top, right, bottom] or [horizontal, vertical] or just a number for equal margins
    pageMargins: [left, top, right, bottom],
    footer: function (currentPage, pageCount) {
        return {
            margin: [25,10,0,0],
            text:currentPage.toString() + ' / ' + pageCount};
    },
    fontSize: 9,
    header: {
        margin: [0,25,25,25],
        fontSize: 9,
        stack: [
            {columns: [
                {text: ' ', width:150},
                {stack: [
                    {text: 'ASDASD',fontSize: 14},
                    {text: 'DGDFGDF',fontSize: 12},
                    {text: 'ASDA 225522',fontSize: 12}
                ]},
                {stack: [
                    {text: 'EMS',fontSize: 11},
                    {text: '22/02/2016',fontSize: 11},
                    {text: usuario, fontSize: 11}],
                    alignment: 'right',
                    width: 85
                }
            ]
            },
            {
                margin: [25, 15, 0, 0],
                columns: ['IMERC RECIB', {text: 'SIMPLE', alignment: 'right'}]
            },
            {
                margin: [25,0,0,0],
                columns:[
                    {text:[{text:'Descargado por: ',bold:true}, 'Cliente']},
                    {text:[{text:'Mercaderia Paletizada? ',bold:true}, 'Granel']},
                    {text:[{text:'Utiliza DAN? ',bold:true}, 'SI']}
                ]
            },
            {
                margin: [25,0,0,0],
                columns:[
                    {text:[{text:'Bulks Armados: ',bold:true}, '7.0'], width:95},
                    {text:[{text:'Bulks Flejados: ',bold:true}, '7.0'], width:95},
                    {text:[{text:'Area ocupada: ',bold:true}, '19.0 m²']},
                    {text:[{text:'Volumen ocupado: ',bold:true}, '37.0 m³']},
                    {text:[{text:'Peso kilogramos: ',bold:true}, '3200.0']}
                ]
            }
        ]
    },
    content: [
        {
            fontSize: 9,
            table:{
                headerRows:1,
                widths: [ 60, 60, 145, 135, 55, 55 ],
                body:[
                    [
                        'Codigo 1',
                        'Codigo 2',
                        'Descripcion Mercaderia',
                        {stack:['$$%%%', {columns:['Dec', 'Rec', 'Dif']}],alignment: 'center'},
                        'UM',
                        'EM'
                    ],[
                        '10094461 2',
                        ' ',
                        'Exhividres de mesa',
                        {stack:[{columns:['0','0','0']}]},
                        'BTOS',
                        'Resellado'
                    ],[
                        '10094461 2',
                        ' ',
                        'Exhividres de mesa',
                        {stack:[{columns:['0','0','0']}]},
                        'BTOS',
                        'Roto'
                    ],
                    [' ',' ', ' ', {stack:[{columns:['2222','3232','2']}]}, ' ',' ']]
            }
        },
        {margin:[0,10,0,0], text:[{text:'Observaciones: ', bold:true}, 'ASDASDASDAS']},
        {margin:[0,20,0,0], stack:[
            {columns:['CLIENTE', {text:' ',width:50}, 'Recibe Mercaderia']},
            {columns:['Entrega de Mercaderia', {text:' ',width:50}, 'Jefe de Bodega']},
            {columns:['M1212121 _____________________', {text:' ',width:50}, 'Milton Marroquin _____________________']},
            {columns:[' ', {text:'SELLO',width:50}, ' ']},
            {columns:['Visto Bueno', {text:' ',width:50}, 'Fecha: _____________________']},
            {columns:['Jefe de Produccion', {text:' ',width:50}, 'Hora: _____________________']},
            {columns:['Ing. Roberto Estrada_____________________', {text:' ',width:50}, 'Funcionario de Aduana _____________________']}
        ]}
    ]
};
var asdf = pdfMake.createPdf(dd);
asdf.open(); </script> </body> </html>

Upvotes: 1

Views: 7465

Answers (1)

jmcgriz
jmcgriz

Reputation: 3358

The problem is that the code is automatically trying to generate the PDF in a popup window. If the popup gets blocked, that causes errors to occur within the pdfmake script (which seems like a big problem on their part, that error should be handled quite a bit more gracefully than that)

I tried your code locally and it failed, but once I enabled popups, it worked as expected. I'm not sure if there's another way to use the library that doesn't rely on window.open(), but it might be worth looking into

The bit of problem code in pdfmake.js is here:

Document.prototype.open = function(message) {
    // we have to open the window immediately and store the reference
    // otherwise popup blockers will stop us
    var win = window.open('', '_blank');

    try {
        this.getDataUrl(function(result) {
            win.location.href = result;
        });
    } catch(e) {
        win.close();
        throw e;
    }
};

If you want a quick solution, download that script, host it locally, and change the above section to this:

Document.prototype.open = function(message) {
    // we have to open the window immediately and store the reference
    // otherwise popup blockers will stop us
    //var win = window.open('', '_blank');

    try {
        this.getDataUrl(function(result) {
          document.querySelector('iframe').src = result;
        });
    } catch(e) {
        win.close();
        throw e;
    }
};

Then you just need an iframe somewhere on your page, and you can swap document.querySelector('iframe') with a specific reference to that particular frame. It's still probably better to find a way to get it working without editing the include like that, but it at least proves that the popup is indeed the source problem.

Upvotes: 2

Related Questions