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

Chris picture Chris · Oct 22, 2017 · Viewed 11.8k times · Source

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?

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.

Answer

ljubadr picture ljubadr · Oct 22, 2017

EDIT: while this answer worked at the time that it was posted and accepted, looks like it's not the case anymore. For anyone looking for the updated solution, other answers are up to date

Yevgeniy Afanasyev

Alexander Gallego L.

Artistan

Because this is accepted answer, I will add the new the solution, but the credit for this should go to people who provided updated answers

window.$ = window.jQuery = require( 'jquery' );

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

Original answer

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 'jquery/dist/jquery.slim';
import * as dt from 'datatables.net';
import * as dt_bs from 'datatables.net-bs';

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