$(…).DataTable is not a function when using Laravel Mix


$(…).DataTable is not a function when using Laravel Mix



I struggle using Laravel Mix and DataTables. The issue I have is that when I compile down my .js-files etc., each time I would then visit a page that would execute a jQuery datatable, the follwoing error is thrown:



The error is:


jQuery.Deferred exception: $(...).DataTable is not a function TypeError: $(...).DataTable is not a function
Uncaught TypeError: $(...).DataTable is not a function



From what I understand, $(...).DataTable is not a global variable, but how can I make sure that it is accessible "on a global scope" / within my app?


$(...).DataTable



The following is my setup:



app.js


import jquery from 'jquery/dist/jquery.slim'
import 'bootstrap-sass'
import 'datatables.net';
import dt from 'datatables.net-bs';

window.$ = window.jQuery = jquery;



webpack.mix.js


mix
.js('resources/assets/admin/js/app.js', 'js/')
.extract([
'jquery', 'bootstrap-sass', 'datatables.net', 'datatables.net-bs'
])
.autoload({
jquery: ['$', 'window.jQuery', 'jQuery', 'jquery'],
DataTable : 'datatables.net-bs'
})



Any idea would be highly appreciated.





Check datatables.net-bs npm page. var $ = require( 'jquery' ); require( 'datatables.net-bs' )( window, $ )
– ljubadr
Oct 22 '17 at 2:15


var $ = require( 'jquery' ); require( 'datatables.net-bs' )( window, $ )





same goes for datatables.net. From npm page var $ = require( 'jquery' ); require( 'datatables.net' )( window, $ );
– ljubadr
Oct 22 '17 at 2:44


var $ = require( 'jquery' ); require( 'datatables.net' )( window, $ );





I have tried that before and it caused this issue: Uncaught ReferenceError: $ is not defined. Is there no way to import it?
– Chris
Oct 22 '17 at 3:15





Updated answer, import $ from 'jquery';
– ljubadr
Oct 22 '17 at 3:37


import $ from 'jquery';





Or, in your case, import $ from 'jquery-slim'. I missed that's slim version
– ljubadr
Oct 22 '17 at 3:39


import $ from 'jquery-slim'




3 Answers
3



Looking at npmjs pages for datatables.net and the datatables.net-bs



They should be initialized like this


var $ = require( 'jquery' );
require( 'datatables.net' )( window, $ );
require( 'datatables.net-bs' )( window, $ );



Which we could transform into this


var $ = require( 'jquery' );
var dt = require( 'datatables.net' )
var dt_bs = require( 'datatables.net-bs' )

// in this call we're attaching Datatables as a jQuery plugin
// without this step $().DataTable is undefined
dt( window, $ )
// we need to do the same step for the datatables bootstrap plugin
dt_bs( window, $ )



But if you really want to use import .. from .., take a look into MDN import documentation


import .. from ..


import $ from 'jquery/dist/jquery.slim';
import * as dt from 'datatables.net';
import * as dt_bs from 'datatables.net-bs';

dt( window, $ )
dt_bs( window, $ )





I'm having the error with the first approach saying: Uncaught TypeError: Cannot set property '$' of undefined
– Yevgeniy Afanasyev
Apr 24 at 0:08





@YevgeniyAfanasyev - i am having the same issue with most recent packages, any solution?
– Artistan
Jun 29 at 16:16





I posted my answer to this question.
– Yevgeniy Afanasyev
yesterday



For the latest Laravel Mix...



do not invoke the required datatable packages in webpack, leave off the (...)



this will load bootstrap, jquery, datatables, and many of the plugins for datatables without any issues...


window._ = require( 'lodash' );;
window.$ = window.jQuery = require( 'jquery' );;
window.Popper = require('popper.js').default;

// bootstrap
require('bootstrap');

// bootstrap datatables...
require( 'jszip' );
require( 'datatables.net-bs4' );
require( 'datatables.net-buttons-bs4' );
require( 'datatables.net-buttons/js/buttons.colVis.js' );
require( 'datatables.net-buttons/js/buttons.flash.js' );
require( 'datatables.net-buttons/js/buttons.html5.js' );
require( 'datatables.net-buttons/js/buttons.print.js' );
require( 'datatables.net-autofill-bs4' );
require( 'datatables.net-colreorder-bs4' );
require( 'datatables.net-fixedcolumns-bs4' );
require( 'datatables.net-fixedheader-bs4' );
require( 'datatables.net-responsive-bs4' );
require( 'datatables.net-rowreorder-bs4' );
require( 'datatables.net-scroller-bs4' );
require( 'datatables.net-select-bs4' );
// bs4 no js - require direct component
// styling only packages for bs4
require( 'datatables.net-keytable' );
require( 'datatables.net-rowgroup' );
// pdfMake
var pdfMake = require('pdfmake/build/pdfmake.js');
var pdfFonts = require('pdfmake/build/vfs_fonts.js');
pdfMake.vfs = pdfFonts.pdfMake.vfs;



no need for the other code in webpack.mix.js


.extract([
'jquery', 'bootstrap-sass', 'datatables.net', 'datatables.net-bs'
])
.autoload({
jquery: ['$', 'window.jQuery', 'jQuery', 'jquery'],
DataTable : 'datatables.net-bs'
})



Solution (1)



This is how it worked for me:


require('datatables.net');
require('datatables.net-bs4');



Solution (2)



Below is how it was before and it was causing an error: "$(…).DataTable is not a function":


var a = require('../../../node_modules/datatables.net/js/jquery.dataTables.js');
var b = require('../../../node_modules/datatables.net-bs4/js/dataTables.bootstrap4.js');



this is how I fixed it, but the top solution is obviously recommended


window.$.fn.DataTable = a;
window.$.fn.DataTable = b;



Please comment if you know the reasons behind the magic. Question is "why do direct links to js files work differently comparing to links to packages?"






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Comments

Popular posts from this blog

paramiko-expect timeout is happening after executing the command

Export result set on Dbeaver to CSV

Opening a url is failing in Swift