TypeError: t is not a function

TypeError: t is not a function

tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

I'm loading datatables via importmap, but am getting an error:

TypeError: t is not a function
at datatables.net.index-3b6320b7aff88c57cea7a1a00496cbd3.js:7:29968
at new e.exports (datatables.net.index-3b6320b7aff88c57cea7a1a00496cbd3.js:7:83480)

Those lines come from

import t from "jquery";

var xt = l.util.escapeRegex
          , It = t("<div>")[0]
          , At = It.textContent !== a;

Because I'm using esm / importmap, I'm guessing that it's related to jquery, but I have no idea.

<script type="importmap">
{
    "imports": {
        "app": "/assets/app-11210c710ba612bc382cc4e0c6622e85.js",
        "/assets/bootstrap.js": "/assets/bootstrap-c423b8bbc1f9cae218c105ca8ca9f767.js",
        "@symfony/stimulus-bundle": "/assets/@symfony/stimulus-bundle/loader-e1ee9ace0562f2e6a52301e4ccc8627d.js",
        "/assets/styles/app.css": "data:application/javascript,",
        "/assets/@symfony/stimulus-bundle/controllers.js": "/assets/@symfony/stimulus-bundle/controllers-f7bf4ed38fa73998cb671289689b9c74.js",
        "/assets/controllers/hello_controller.js": "/assets/controllers/hello_controller-55882fcad241d2bea50276ea485583bc.js",
        "/assets/@survos/datatables/src/controllers/table_controller.js": "/assets/@survos/datatables/src/controllers/table_controller-8127c5eb836f90a9982b9cc00c7bec82.js",
        "@hotwired/stimulus": "/assets/vendor/@hotwired/stimulus/stimulus.index-b5b1d00e42695b8959b4a1e94e3bc92a.js",
        "bootstrap": "/assets/vendor/bootstrap/bootstrap.index-f0935445d9c6022100863214b519a1f2.js",
        "@popperjs/core": "/assets/vendor/@popperjs/core/core.index-b9d0a7ee9e6f454b15ecdf6a2083b65f.js",
        "bootstrap/dist/css/bootstrap.min.css": "data:application/javascript,const%20d%3Ddocument%2Cl%3Dd.createElement%28%22link%22%29%3Bl.rel%3D%22stylesheet%22%2Cl.href%3D%22%2Fassets%2Fvendor%2Fbootstrap%2Fdist%2Fcss%2Fbootstrap.min-6f3e593392adf34505358c68326dee3d.css%22%2C%28d.head%7C%7Cd.getElementsByTagName%28%22head%22%29%5B0%5D%29.appendChild%28l%29",
        "datatables.net-bs5": "/assets/vendor/datatables.net-bs5/datatables.net-bs5.index-bc562fdcfdee132d01ad7a2adf39b913.js",
        "jquery": "/assets/vendor/jquery/jquery.index-fb3b33d7311be80ac8aa5c367205beba.js",
        "datatables.net": "/assets/vendor/datatables.net/datatables.net.index-3b6320b7aff88c57cea7a1a00496cbd3.js",
        "datatables.net-bs5/css/dataTables.bootstrap5.min.css": "data:application/javascript,const%20d%3Ddocument%2Cl%3Dd.createElement%28%22link%22%29%3Bl.rel%3D%22stylesheet%22%2Cl.href%3D%22%2Fassets%2Fvendor%2Fdatatables.net-bs5%2Fcss%2FdataTables.bootstrap5.min-bcf2600516efeaa82dcc49b89003bded.css%22%2C%28d.head%7C%7Cd.getElementsByTagName%28%22head%22%29%5B0%5D%29.appendChild%28l%29"
    }
}
</script>

While I can't link to a test case, PHP programmers with the Symfony CLI installed can re-create this as follows:


symfony new datatables-demo --webapp --version=next && cd datatables-demo # composer config minimum-stability dev # composer config prefer-stable true composer req symfony/asset-mapper composer req symfony/stimulus-bundle:2.x-dev composer req survos/datatables-bundle bin/console importmap:require bootstrap bin/console make:controller AppController sed -i "s|Route('/app'|Route('/'|" src/Controller/AppController.php cat > templates/app/index.html.twig <<END {% extends 'base.html.twig' %} {% block body %} <table class="table" {{ stimulus_controller('@survos/datatables-bundle/table', {perPage: 5, sortable: true}) }}> <thead> <tr> <th>abbr</th> <th>name</th> <th>number</th> </thead> <tbody> {% for j in 1..12 %} <tr> <td>{{ j |date('2023-' ~ j ~ '-01') |date('M') }}</td> <td>{{ j |date('2023-' ~ j ~ '-01') |date('F') }}</td> <td>{{ j }}</td> </tr> {% endfor %} </tbody> </table> {% endblock %} END symfony server:start -d symfony open:local

Any ideas on what might cause that type error?

This question has an accepted answers - jump to answer

Answers

  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    When I used webpack to install the bundle, the script works as expected. So it likely has something to do with importmap and jquery.

  • allanallan Posts: 63,514Questions: 1Answers: 10,472 Site admin

    Try using:

    "jquery": "https://esm.sh/jquery@3.6.3",
    

    for your jQuery import. jQuery 3.x and earlier does not support ESM importing. It needs to be shimmed.

    Allan

  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    The jquery and the rest of the datatables dependencies are installed locally from jsdelivr when datatables is installed.

    bin/console importmap:require datatables.net-bs5 -vv
    09:50:13 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net-bs5/resolved"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net-bs5/resolved"
    09:50:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/datatables.net-bs5@1.13.6/+esm"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net-bs5@1.13.6/entrypoints"
    09:50:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/datatables.net-bs5@1.13.6/+esm"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net-bs5@1.13.6/entrypoints"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/jquery/resolved?specifier=3.7.1"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net/resolved?specifier=2.1.1"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net/resolved?specifier=2.1.1"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net-bs5/resolved?specifier=1.13.6"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/jquery/resolved?specifier=3.7.1"
    09:50:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/jquery@3.7.1/+esm"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/jquery@3.7.1/entrypoints"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net/resolved?specifier=2.1.1"
    09:50:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/datatables.net@2.1.1/+esm"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net@2.1.1/entrypoints"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net/resolved?specifier=2.1.1"
    09:50:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/datatables.net@2.1.1/+esm"
    09:50:14 INFO      [http_client] Request: "GET https://data.jsdelivr.com/v1/packages/npm/datatables.net@2.1.1/entrypoints"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net@2.1.1/entrypoints"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net-bs5/resolved?specifier=1.13.6"
    09:50:14 INFO      [http_client] Request: "GET https://cdn.jsdelivr.net/npm/datatables.net-bs5@1.13.6/css/dataTables.bootstrap5.min.css"
    09:50:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/jquery@3.7.1/+esm"
    09:50:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/datatables.net@2.1.1/+esm"
    09:50:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/datatables.net@2.1.1/+esm"
    09:50:14 INFO      [http_client] Response: "200 https://cdn.jsdelivr.net/npm/datatables.net-bs5@1.13.6/css/dataTables.bootstrap5.min.css"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/jquery@3.7.1/entrypoints"
    09:50:14 INFO      [http_client] Response: "200 https://data.jsdelivr.com/v1/packages/npm/datatables.net@2.1.1/entrypoints"
    
                                                                                                                            
     [OK] 4 new items (datatables.net-bs5, jquery, datatables.net, datatables.net-bs5/css/dataTables.bootstrap5.min.css)    
          added to the importmap.php!                                                                                       
                                                                                                                 
    
  • allanallan Posts: 63,514Questions: 1Answers: 10,472 Site admin

    I'm not sure then I'm afraid. If there is a minimal way to reproduce the error, I can look into it more.

    Allan

  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    OK, I'll try to do that. We discussed the jdelivr vs your own CDN, are they the same esm modules? I know your example script uses cdn.datatables, but I have to use jsdelivr.

  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    Here's a JS fiddle: https://jsfiddle.net/tacman1123/qnh16kog/2/

    I don't understand how jQuery is loaded in a way that datatables recognizes it. Indeed, using the datatables bookmarklet it says that jQuery isn't loaded.

    Here's the relevant javascript:

    <script type="module">
            import bootstrap from 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm'
            import jQuery from 'https://cdn.jsdelivr.net/npm/jquery@3.7.1/+esm'
            import DataTable from 'https://cdn.jsdelivr.net/npm/datatables.net-bs5@1.13.6/+esm'
    
            let el=document.getElementById('example');
            let dt=new DataTable(el);
        </script>
    
  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    I've been hacking with code like this before the DataTable() call, but it's not working.

    const $ = jQuery;
    global.jQuery = global.$ = $;
    

    Is there a way to initialize DataTable and pass it your own jQuery object?

  • allanallan Posts: 63,514Questions: 1Answers: 10,472 Site admin
    edited October 2023 Answer ✓

    I don't understand how jQuery is loaded in a way that datatables recognizes it.

    DataTables does its own import jQuery from 'jquery';. You can see that in the first line of code in the JS file you are importing (-ish - it looks like jsdelivr is doing some rewriting). It looks like the issue you are having there is that:

    import jQuery from 'jquery';
    

    can't be resolved.

    Indeed, using the datatables bookmarklet it says that jQuery isn't loaded.

    That's just because jQuery isn't in the global scope.

    Is there a way to initialize DataTable and pass it your own jQuery object?

    No - but if you have a global jQuery, then you can just load the DataTables UMD, rather than the ESM version.

    If you are loading module files directly in the browser, you need to tell the browser how to resolve the packages with your importmap. Since the packages themselves do named imports, you need to be able to resolve them. So in this case:

    <script type="importmap">
    {
        "imports": {
            "jquery": "https://esm.sh/jquery@3.6.3",
            "datatables.net": "https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.mjs",
            "datatables.net-bs5": "https://cdn.datatables.net/1.13.6/js/dataTables.bootstrap5.min.mjs"
        }
    }
    </script>
    <script type="module">
            import bootstrap from 'https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/+esm'
            import DataTable from 'datatables.net-bs5'
    
            let el=document.getElementById('example');
            let dt=new DataTable(el);
    </script>
    

    You can probably use jsdelivr if you prefer, I haven't experimented with that.

    Updated example: https://jsfiddle.net/xkgo17ut/ .

    Import maps have a lot of constraints, as I wrote about in the blog post on this topic. Personally I don't feel it is ready for production use yet.

    Allan

  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    Ryan discovered this issue:

    import e from"/npm/datatables.net@2.1.1/+esm";

    and reported it https://github.com/DataTables/DataTablesSrc/issues/246

    He also provided this commentary:

    So, it's a "bug" on their side. Really, an accident - but it's something that should be fixed on their end. The workaround, in AssetMapper, is, after running importmap:require datatables.net-bs5, manually go into importmap.php, adjust the datatables.net version to 1.13.6 (to match datatables.net-bs5), then run importmap:install.

  • tacman1123tacman1123 Posts: 198Questions: 46Answers: 1

    Thanks for the fiddle! Great to see it working inside a module.

    I really hope we can get it working on jsdelivr, though.

Sign In or Register to comment.