Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maximum call stack size exceeded error in chrome using jquery templates

I'm loading more than 7000 records and displaying them on my page.

Firefox is doing just fine but I'm having an error using Chrome

Partial code:

<tbody>
    {{each(i, item) value}}
    <tr>
        <td class="item_action">
            <a class="edit_item" data-item="${item.id}">
                <img src="path/to/image_edit.png" />
            </a>

            <img src="path/to/image_separator.png" />

            <a class="delete_item" data-item="${item.id}">
                <img src="path/to/image_delete.png" />
            </a>
        </td>
        <td class="item_name">${item.name}</td>
    </tr>
    {{/each}}
</tbody>

If instead of the above I render this:

<tbody>
    {{each(i, item) value}}
    <tr>
        <td class="item_name">${item.name}</td>
    </tr>
    {{/each}}
</tbody>

Then Chrome has no problem. So I guess it has something to do with the size of HTML I'm trying to render as I've read here.

Is there a solution for this issue? I

like image 455
Matías Cánepa Avatar asked Apr 10 '26 01:04

Matías Cánepa


1 Answers

I had the same issue. If you look to jquery.tmpl code you can find

function build( tmplItem, nested, content ) { ... 

The problem is in

jQuery.map( content, function( item ) {

for each item in the 'content' array (and you have i guess more than 50000 elements here) should be called function. This is too much for Webkit browsers. This code was modified a little to solve my issue:

function build( tmplItem, nested, content ) {
    // Convert hierarchical content into flat string array
    // and finally return array of fragments ready for DOM insertion
    var processMap = function(){
        var result = [];
        var items = [];
        for(var i = 0; i<content.length; (i = i+10000)){
            var subcontent = content.slice(i, i+10000);
            items =  jQuery.map( subcontent, function( item ) {
                        return (typeof item === "string") ?
                            // Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM.
                            (tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) :
                            // This is a child template item. Build nested template.
                            build( item, tmplItem, item._ctnt );
            });
            result = result.concat(items);
        }
        return result;
    };
    var frag, ret = content ?  processMap():
    // If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}.
    tmplItem;
    if ( nested ) {
        return ret;
    } ...

So jQuery.map function process each 10000 elements and doesn't allow 'Maximum call stack size exceeded'.

This is a crude solution but hope it helps you :)

like image 100
Kroshchuk Lyudmila Avatar answered Apr 11 '26 15:04

Kroshchuk Lyudmila



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!