Uncaught TypeError: Cannot read properties of undefined (reading 'classes')
Uncaught TypeError: Cannot read properties of undefined (reading 'classes')
Link to test case: (unable to provide because it sits behind a secure/authenticated area)
Debugger code (debug.datatables.net): (can't get it to work with webpack because jQuery is not defined for the console to use)
Error messages shown:
Uncaught TypeError: Cannot read properties of undefined (reading 'classes')
at ./node_modules/datatables.net-bs4/js/dataTables.bootstrap4.mjs (admin.js:7683:93)
at __webpack_require__ (runtime.js:80:30)
at Module.<anonymous> (admin.js:12:160)
at ./assets/js/admin.js (admin.js:66:30)
at __webpack_require__ (runtime.js:80:30)
at checkDeferredModules (runtime.js:46:23)
at Array.webpackJsonpCallback [as push] (runtime.js:33:19)
at admin.js:1:57
Description of problem:
For a couple years my code has been fine, something in the underlying datatables packages seems to have changed and I've been getting the following error below.
I've tried many of the suggestions in various posts about using bootstrap datatables with encore webpack and I can't get any clarity so I am showing my specifics in hopes someone else can help me.
admin.js, this imports the required datatables packages:
// Require jQuery
let $ = require('jquery');
global.$ = global.jQuery = $;
window.$ = window.jQuery = $;
import dt from 'datatables.net-bs4';
dt(window, $);
import dtb from 'datatables.net-buttons';
dtb(window, $);
import dtb5 from 'datatables.net-buttons/js/buttons.html5.js';
dtb5(window, $);
import dtbp from 'datatables.net-buttons/js/buttons.print.js';
dtbp(window, $);
require('bootstrap');
$(document).ready(function () {
let enrollmentTable = $('#enrollment_report');
if (enrollmentTable.length) {
enrollmentTable.DataTable({
dom: 'lfrtiBp',
buttons: [
'csv'
]
});
}
});
my webpack.config.js related to imports-loader:
.addLoader({ test: /datatables\.net.*/, loader: 'imports-loader?define=>false' })
my package.json as related to datatables, loaded with yarn. I've tried moving to the latest versions, but that either didn't help or gave me other "undefined" type errors.
"datatables.net": "^1.10.20",
"datatables.net-bs4": "^1.10.23",
"datatables.net-buttons": "^1.6.5",
"datatables.net-buttons-bs": "^1.6.5",
"imports-loader": "^0.8.0",
The source line where the error comes from:
at ./node_modules/datatables.net-bs4/js/dataTables.bootstrap4.mjs
/* Default class modification */
jquery__WEBPACK_IMPORTED_MODULE_0__.extend( datatables_net__WEBPACK_IMPORTED_MODULE_1__.ext.classes, {
sWrapper: "dataTables_wrapper dt-bootstrap4",
sFilterInput: "form-control form-control-sm",
sLengthSelect: "custom-select custom-select-sm form-control form-control-sm",
sProcessing: "dataTables_processing card",
sPageButton: "paginate_button page-item"
} );
I suspect the mystery to solve is where is this ".ext.classes" supposed to get defined?
Appreciate any tips on things to try, I've been hitting the wall for several days now and not getting any closer.
Thanks,
Kevin
Answers
Hi Kevin,
I suspect you are running into this issue. Specifically, if you are using ES imports (which I guess is happening in this case) then:
Should become:
And others such as Buttons:
Let me know how you get on with that.
Allan
Hi Allan,
Thank you so much for the response/tips.
So I did some experimenting this morning and have discovered the following:
First, upgraded to your latest as so.
Next, I was able to get raw datatables (i.e. no bootstrap4 styling) functioning with just (either way worked the same) using:
OR
The issue is that as soon as I try to do the same type of importing with '-bs4' packages I get my error. My understanding is that I can just import the '-bs4' packages and it will pull in what is needed from the base 'datatables.net' packages, if that's incorrect please let me know. Here is what I tired which always results in the undefined (reading 'classes') error in my original post.
OR
Btw, I did try something like this as well, but resulted in the exact same error:
Not sure if that's helpful or just muddies up the water.
-Kevin
Could you show me all the DataTables imports you are using? There is actually a packaging issue with some of the current extensions which means you need to include their core library as well as the Bootstrap 4 integration - e.g.:
Only the second line should be needed, but at the moment with a CommonJS loader both are needed.
Do you know if WebPack is using CommonJS - I'm guessing it probably is in which case you'd still need the
dt(window, $);
parts (the CommonJS signature is unchanged)? The ESM signature is different and that what we might initially be running into here.Allan
I believe webpack is using CommonJS. Which begs the question why are we hitting the error in .mjs file, I thought it'd be trying to load the .js version?
Here are all my DataTables imports:
Note, if I remove the imports related to bs-4, I will get the following error:
which reveals at the source here on line 8:
-Kevin
Hi,
I have exactly the same problem, have you found a workaround for this bug?
Apologies - I lost track of this thread.
Since ESM is being used, you should use:
i.e. no need to execute them as a function.
If that doesn't help resolve the issue, please create a repo of StackBlitz example showing the issue I can dig into it more.
Thanks,
Allan
Thank you very much for this advice which solved my similar problem. As a tip for anyone else coming here from google, if you still get the error check if you have imported any js files directly from eg the buttons package such as
import 'datatables.net-buttons/js/buttons.print.js'
and make sure to point to the mjs files instead.Hi Allan, thanks for coming back, I too was off on other projects.
So, I removed every DT package and started over from scratch.
Even the most minimal imports and leaving bootstrap stuff out of it, I still fail:
package.json:
Error:
Starting to feel like this is something inside my setup since others seem to be having better luck than I. I'll keep poking around and see what I can uncover. If I get a chance I'll drop something in StackBlitz per your suggestion.
If you do
console.log(DataTable)
- what does the console show please?Allan
In my project, I have the same issue:
results in the following error:
Which is this code
At that position,
console.log($.fn)
is undefined, so$.fn.dataTable
and$.fn.DataTable
are undefined too, of course.Thanks! How are you compiling this? I assume you are using a bundler such as Vite, or Webpack? Can you give me instructions on how to recreate that setup so I can dig into it?
Thanks,
Allan
I'm using Webpack indeed, unfortunately I'm not very experienced with it and it is part of a larger project (in fact using Webpack Encore). I'll see if I can make a minimal reproduction of the problem
TJV i'm having the same error. Does anyone already have a solution?!
If you can create a mini-repo showing the issue, I can debug it.
Allan
Hi Allan,
I was finally able to find the time to fire up a new symfony project from scratch and get datatables working with symfony 6, webpack, encore, bootstrap5.
So, whatever is going on with my older project is a matter of conflicts somewhere else in all of my dependencies.
Anyway here are the basics and I hope it can help others.
webpack.config.js:
app.js:
styles/app.css:
package.json:
Nice, thanks for sharing,
Colin