Search code examples
javascriptjqueryhtmldatatablesthymeleaf

Could not parse as expression defining a DataTable in Thymeleaf


I have a basic SpringBoot 2.0.4.RELEASE app. using Spring Initializer, JPA, embedded Tomcat, Thymeleaf template engine, and package as an executable JAR file.

I have this definition of a datatable in a template

    <script th:inline="javascript">
            /*<![CDATA[*/ 

        $.fn.dataTable.ext.errMode = 'throw';

            var ajaxUrl = /*[[@{${ajaxUrl}}]]*/ "";

                var table = $('#smsEventTable').DataTable( {
                    order: [[ 0, "desc" ]],
                    select: true,
                    bLengthChange: false,
                    stateSave: true,
                    pageLength: 20,
                    ajax: ajaxUrl, 
                       "columns": [
                           { data: 'id' },
                           { data: 'smsId' },
                           { data: 'companyName' },
                           { data: 'description' },
                           { data: 'battery', className: 'col_battery' },
                           { data: 'dateTime' },
                           { data: 'signal' },           
                           { data: 'data' },
                           { data: 'alarm' }
                       ] 
                });

            /*]]>*/
</script>

But the first time I load the page and there is no data I got this error:

Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: " 0, "desc" " (template: "/sms/smsList" - line 273, col 12)

Solution

  • The problem here is this expression: order: [[ 0, "desc" ]],. Because that expression has double brackets ([[ and ]]), Thymeleaf is trying to evaluate it as an inline expression. The simplest way to fix this is to format it differently by break up the brackets:

    order: [ [0, "desc"] ],
    

    or

    order: [
        [0, "desc"]
    ],
    

    You could also break up your JavaScript into two blocks (disabling inlining in the second one) like this:

    <script th:inline="javascript">
        var ajaxUrl = /*[[@{${ajaxUrl}}]]*/ "";
    </script>
    
    <script th:inline="none">
    /*<![CDATA[*/ 
        $.fn.dataTable.ext.errMode = 'throw';
    
        var table = $('#smsEventTable').DataTable({
            order: [[0, "desc"]],
            select: true,
            bLengthChange: false,
            stateSave: true,
            pageLength: 20,
            ajax: ajaxUrl, 
               "columns": [
                   {data: 'id'},
                   {data: 'smsId'},
                   {data: 'companyName'},
                   {data: 'description'},
                   {data: 'battery', className: 'col_battery'},
                   {data: 'dateTime'},
                   {data: 'signal'},           
                   {data: 'data'},
                   {data: 'alarm'}
               ] 
        });
    /*]]>*/
    </script>