Error in non-jQuery initialization with one option
Error in non-jQuery initialization with one option
Hi,
I've had success with the simplest form of Non-jQuery initialization below.
import DataTable from "datatables.net-bs5";
export default function initTable() {
let table = new DataTable('#example');
return table;
}
Then following the example in Non-jQuery Options,
I added one option "{ paging: false }" to the code in the successful simple initialization of DataTable.
import DataTable from "datatables.net-bs5";
export default function initTable() {
let table = new DataTable('#example', { paging: false });
return table;
}
This code gave an error below in jest's test.
And this code is for this attempt, published at https://github.com/SatoTake2019/datatables-webpack
I would appreciate any advice on how to make this successful.
Thank you in advance.
console.error
Error: Uncaught [TypeError: Cannot read properties of undefined (reading 'dataTable')]
at reportException (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\helpers\runtime-script-errors.js:66:24)
at innerInvokeEventListeners (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:353:9)
at invokeEventListeners (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:286:3)
at DocumentImpl._dispatch (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:233:9)
at DocumentImpl.dispatchEvent (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:104:17)
at Document.dispatchEvent (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:241:34)
at Object.dispatchEvent (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\__tests__\tables.test.js:10:18)
at Promise.then.completed (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\utils.js:289:28)
at new Promise (<anonymous>)
at callAsyncCircusFn (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\utils.js:222:10)
at _callCircusTest (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:248:40)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at _runTest (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:184:3)
at _runTestsForDescribeBlock (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:86:9)
at _runTestsForDescribeBlock (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:81:9)
at run (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:26:3)
at runAndTransformResultsToJestFormat (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:120:21)
at jestAdapter (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:79:19)
at runTestInternal (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-runner\build\runTest.js:367:16)
at runTest (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-runner\build\runTest.js:444:34) {
detail: TypeError: Cannot read properties of undefined (reading 'dataTable')
at new Object.<anonymous>.module.exports (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\datatables.net-bs5\js\dataTables.bootstrap5.js:27:16)
at initTable (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\initTable.js:4:17)
at Document.<anonymous> (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\__tests__\tables.test.js:6:34)
....................................(omitted several lines due to character limit).........................................
at DocumentImpl._dispatch (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:233:9)
at DocumentImpl.dispatchEvent (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\events\EventTarget-impl.js:104:17)
at Document.dispatchEvent (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jsdom\lib\jsdom\living\generated\EventTarget.js:241:34)
at Object.dispatchEvent (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\__tests__\tables.test.js:10:18)
at Promise.then.completed (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\utils.js:289:28)
at new Promise (<anonymous>)
at callAsyncCircusFn (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\utils.js:222:10)
at _callCircusTest (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:248:40)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at _runTest (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:184:3)
at _runTestsForDescribeBlock (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:86:9)
at _runTestsForDescribeBlock (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:81:9)
at run (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\run.js:26:3)
at runAndTransformResultsToJestFormat (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapterInit.js:120:21)
at jestAdapter (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-circus\build\legacy-code-todo-rewrite\jestAdapter.js:79:19)
at runTestInternal (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-runner\build\runTest.js:367:16)
at runTest (D:\PyCharmProjects\datatables-webpack\myapps\static\js\__datatables__\node_modules\jest-runner\build\runTest.js:444:34),
type: 'unhandled exception'
}
8 |
9 | const event = new Event('DOMContentLoaded');
> 10 | document.dispatchEvent(event);
| ^
11 | });
12 | });
at VirtualConsole.<anonymous> (node_modules/jest-environment-jsdom/build/index.js:60:23)
at reportException (node_modules/jsdom/lib/jsdom/living/helpers/runtime-script-errors.js:70:28)
at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:353:9)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)
at DocumentImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)
at DocumentImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)
at Document.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)
at Object.dispatchEvent (__tests__/tables.test.js:10:18)
FAIL __tests__/tables.test.js
test Datatable initialization
× init test (42 ms)
● test Datatable initialization › init test
TypeError: Cannot read properties of undefined (reading 'dataTable')
2 |
3 | export default function initTable() {
> 4 | let table = new DataTable('#example', { paging: false });
| ^
5 | return table;
6 | }
7 |
at new Object.<anonymous>.module.exports (node_modules/datatables.net-bs5/js/dataTables.bootstrap5.js:27:16)
at initTable (initTable.js:4:17)
at Document.<anonymous> (__tests__/tables.test.js:6:34)
at Document.callTheUserObjectsOperation (node_modules/jsdom/lib/jsdom/living/generated/EventListener.js:26:30)
at innerInvokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:350:25)
at invokeEventListeners (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:286:3)
at DocumentImpl._dispatch (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:233:9)
at DocumentImpl.dispatchEvent (node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:104:17)
at Document.dispatchEvent (node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:241:34)
at Object.dispatchEvent (__tests__/tables.test.js:10:18)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
that's all
This question has accepted answers - jump to:
Answers
Hi,
Thanks for the link to the repo. I'm afraid you are going to have to give me instructions on how I can reproduce the error though / build the code in the repo. I don't see a package.json file for example?
Allan
Hi allan,
Sorry for my lack of information.
The JavaScript base directory is https://github.com/SatoTake2019/datatables-webpack/tree/jest-err-with-one-option/myapps/static/js/__datatables__/. Deep down
So when you open this repo in an IDE like Microsoft's VSCode, open the "__datatables__" folder. There is package.json in that directory, so if you have installed yarn globally, "yarn test" will run Jest tests.
takeshi
... and I found out one more thing…
I took the next step with the above code which did not pass Jest's test.
When I successfully built the above code with webpack and started Django's runserver, bundle.js no longer gave me errors in the browser.
This means that the code built with webpack is usable, but it also requires unit tests to be successful.
Can you tell me how to get it to pass Jest tests?
Thanks for the directions. I've just tried:
I'm not sure what I'm missing?
Allan
Allan, thank you for trying.
However, the git branch you tried seems to be the "trying" branch, not the "jest-err-with-one-option" branch that causes Jest to error. The branch that causes the error has the option {paging: false} in the initialization expression.
In this repository, success and error cases are distinguished by placing them in their respective git branches.
I think that the explanation is not enough for other people to reproduce the error, so I am going to rewrite part of it, including how to start Django's runserver.
Please wait a few days.
Takeshi
Hello Allan,
I cleaned up the project above, added some more explanations, and created another repository called datatables-jest-webpack. Please try again with the new repository.
The old repository posted above will be removed in a few days.
How to reproduce each case.
In this repository, success and error cases are differentiated by placing them in their respective git branches. The result of each branch is in the table below.
Then if you reproduce the error case.
These commands result in a jest error.
Yet a build using the following command succeeds:
Then run the Django's runserver gives no error.
This means that bundled js code built with webpack is available in production.
However, I need the Jest unit test to pass at the same time, so please tell me how to do that.
(README.md in this repository also has detailed instructions on how to reproduce)
I tried to write the README and this post as carefully as possible, but I'm not good at English, so I hope I can convey it well.
Takeshi
Hi Takeshi,
Many thanks for documenting this so thoroughly! Unfortunately, I don't have a direct answer to resolve this at the moment, but I do know what is going wrong.
What is happening is that the Webpack build is loading DataTables using ES modules. Jest however is using the UMD loader (specifically CommonJS). Those two have slightly different export signatures, which is why this error is being encountered.
I've read over this part of the Jest documentation about using ESM, and this SO post on the topic, but haven't been able to resolve it.
I can tell that it isn't using the ESM files for DataTables due to this line in the error back trace:
If it were ESM then
dataTables.bootstrap5.mjs
would have been the file that was loaded.I know this is a pain, but I think this is actually a good thing, since it shows that the environment Jest is running and the one that is used in the browser is not the same - they are using two different files, so the tests aren't actually testing what the site is running!
The key will be to somehow tell Jest to run the ESModules for DataTables. But how to do that (since I couldn't with the documentation on the Jest site), I'm afraid I just don't know.
I think you'll need input from someone who is far more experienced with Jest that I am to get it fully resolved (if you do - please post back with that information so I can learn as well!).
Allan
Hello Allan,
Thanks for the clarification and helpful link information that Jest needs to load the ESModule for DataTables.
In fact, when I was testing some variations of the DataTable initialization code yesterday, I found that a Jest's contributor said "We don't support amd, you must use umd" in the Jest's Issue Tracker. And in an article Hands-on Node.js native ESM — Wantedly application migration example (written in Japanese though) I read, it says, “Libraries like Jest and Storyshot, which tweak Node.js's module system or are tightly coupled to them, so adapting to ESM can be difficult.” So It seems that the solution is not easy. But if I have any progress or information regarding this problem, I will put another post separately on this forum to share the information.
And one more thing, It's not the root solution to the above problem, but I'm trying another workaround.
Before closing this topic, I would like to ask you to see whether it makes sense from your experience.
Please give me a few days to test it some more and implement it in another branch of my repository.
thank you,
takeshi
Hi Takeshi,
Module loaders are a bit of a nightmare! A UMD (Universal Module Loader) is a wrapper that will allow a piece of code to be used in any of three environments:
So I think the Jest contributor misspoke slightly there - they support CommonJS, which is one of the loaders supported by a UMD.
What really messes things up is the current transition that the Javascript world is going through to EM Modules - a forth loader type! Ultimately it will be excellent, but it needs all the libraries to catch up.
There are three options and I can see here:
I haven't tested it, but you might be able to do something like:
Personally I really wouldn't like to do that though, since as I mentioned, it means your test and "real" code are going through two different paths!
The best way would be to see if Jest can be made to run with the ES module.
Allan
Hello Allan,
Yes, the initialization workaround I was trying was to conditionally separate the two paths. The code is below:
I created a new branch workaround-for-jest and put the above code in this branch of the same repository.
I'm not sure if code like this makes sense, but none of the Jest tests, Webpack builds, or running in the browser gave any errors.
Also, since the options are written in one place, even if there is a change, it is OK to modify only one place. So I can test my own customizations.
Regarding the table object returned by the initialization function, the representation of the object is different between Jest and the browser, but it seems to have the same functionality. With table.data(), I could see the data for each item in the table.
And although I wrote only one test, I checked if the optional function before and after initialization is enabled in the test file static/js/__datatables__/__tests__/index.test.js.
Thanks for posting your workaround. As you say, a bit nasty, but if it works...
Allan