Reputation: 12096
I've been upgrading a Symfony application from 3.4
to 4.2.2
, everything is fine but I cannot get DataTables to function via yarn install and webpack encore with angular-datatables.
Yarn install:
yarn add [email protected]
yarn add [email protected]
yarn add [email protected]
yarn add [email protected]
yarn add [email protected]
Added those files to my Webpack app.js
along with jQuery:
var $ = require('jquery');
require('datatables.net');
require('datatables.net-dt');
require('angular');
require('angular-datatables');
Included the app.js
inside of my Webpack config file:
var Encore = require('@symfony/webpack-encore');
Encore
.setOutputPath('public/build/')
.setPublicPath('/build')
.addEntry('app', './assets/js/app.js')
.enableSingleRuntimeChunk()
.cleanupOutputBeforeBuild()
.enableBuildNotifications()
.enableSourceMaps(!Encore.isProduction())
.enableVersioning(Encore.isProduction())
.autoProvidejQuery()
;
module.exports = Encore.getWebpackConfig();
and included the above in my front-end template via:
{{ encore_entry_script_tags('app') }}
The above results in the following Javascript error which seems to show the DataTables API is not accessible.
Uncaught TypeError: Cannot read property 'Api' of undefined
at initAngularDataTables (angular-datatables.js:478)
at Object.invoke (angular.js:4523)
/* @ngInject */
function initAngularDataTables() {
if ($.fn.DataTable.Api) {
/**
* Register an API to destroy a DataTable without detaching the tbody so that we can add new data
* when rendering with the "Angular way".
*/
$.fn.DataTable.Api.register('ngDestroy()', function(remove) {
remove = remove || false;
I've tried the following hacky fix but it means I have to have my Angular code in the same app.js file else it doesn't work. It also means some functions still fail...
global.$ = global.jQuery = require('jquery');
require('jquery-ui');
require('bootstrap');
require('admin-lte');
require('datatables.net-dt');
global.moment = require('moment');
$.fn.dataTable = $.fn.DataTable = global.DataTable = require('datatables.net');
Error:
TypeError: _oTable.ngDestroy is not a function
at _destroyAndCompile (angular-datatables.js:947)
Upvotes: 5
Views: 1084
Reputation: 17556
Your project has datatables.net
and datatables.net-dt
as dependency, and both of them has their own dependency (jQuery>1.7)
. If you don't specify a jQuery version for your project, your dependency tree end up with the latest version of jQuery which is also used by your dependencies.
├─[email protected]
├─[email protected]
└─[email protected]
But if you specify an old version of jQuery, your dependency tree end up fetching the latest version of jQuery for your dependencies (yarn does it, npm does not, I don't know why).
├─[email protected]
├─[email protected]
│ └─[email protected]
└─[email protected]
└─[email protected]
As a result, you have 2 different jQuery in your porject.
const jQuery = require('jquery')
console.log(jQuery.fn.jquery) // logs 2.1.4
const DataTable = require('datatables.net')
console.log(DataTable.$.fn.jquery) // logs 3.3.1
As DataTable binds itself to an encapsulated instance of jQuery, jQuery.fn.dataTable
is
obviously undefined
. To fix this issue, just use the latest version of jQuery in your
project. Or you can recommend yarn to use a fixed version of jQuery for all of it's dependencies adding a resolution directive to your package.json
file.
"dependencies": {
"angular": "1.4.8",
"angular-datatables": "0.6.2",
"datatables.net": "1.10.19",
"datatables.net-dt": "^1.10.19",
"jquery": "2.1.4"
},
"resolutions": {
"jquery": "2.1.4"
}
Then execute yarn install
command, and your unwanted jQuery installations will be taken care of.
Upvotes: 2