MENU

【DataTables】よくあるエラーまとめ

DataTablesのエラーは、初期化の重複、列数の不一致、Ajaxレスポンスの崩れなど、原因がある程度パターン化されています。

この記事では、実装中によく遭遇する警告やエラーを、どこを見れば切り分けられるかに寄せて整理します。

目次

公式ページ

まず確認すること

DataTablesでエラーが出たときは、最初に以下を確認すると原因を絞り込みやすいです。

  • ブラウザのコンソールに表示されているエラー文
  • DataTablesを初期化している対象のtable要素
  • theadの列数とtbodyの列数
  • columnscolumnDefsの定義数
  • Ajaxのレスポンス内容
  • JavaScript、CSS、jQuery、DataTablesの読み込み順

特にAjaxを使っている場合は、ブラウザの開発者ツールでNetworkタブを開き、DataTablesが呼び出しているAPIのステータスコードとレスポンス本文を確認します。

Cannot reinitialise DataTable

以下のような警告です。

DataTables warning: table id=usersTable - Cannot reinitialise DataTable.

これは、すでにDataTablesとして初期化済みのテーブルに対して、もう一度初期化オプションを渡したときに発生します。

new DataTable('#usersTable', {
    paging: false
});

new DataTable('#usersTable', {
    searching: false
});

DataTablesの初期化オプションは、基本的に初期化時だけ指定できます。
あとから設定を追加するつもりで再度new DataTable()を実行すると、この警告が出ます。

修正方法

初期化オプションは1回にまとめます。

new DataTable('#usersTable', {
    paging: false,
    searching: false
});

すでに初期化済みかどうかを確認したい場合は、DataTable.isDataTable()を使います。

let table;

if (DataTable.isDataTable('#usersTable')) {
    table = DataTable('#usersTable');
} else {
    table = new DataTable('#usersTable', {
        paging: false,
        searching: false
    });
}

同じ設定で既存のインスタンスを取得したいだけなら、retrieve: trueも使えます。

const table = new DataTable('#usersTable', {
    retrieve: true,
    paging: false
});

ただし、retrieve: trueは既存のDataTablesインスタンスを返すための指定です。
すでに初期化済みの場合、あとから渡した新しい設定に変更されるわけではありません。

設定そのものを変えて作り直したい場合は、destroy: trueを使う方法もあります。

new DataTable('#usersTable', {
    destroy: true,
    searching: false
});

ただし、単にデータを再取得したいだけなら、破棄して作り直すよりajax.reload()などのAPIを使う方が効率的です。

Requested unknown parameter

以下のような警告です。

DataTables warning: table id=usersTable - Requested unknown parameter 'name' for row 0, column 1

DataTablesが列に表示するデータを取得しようとしたものの、指定されたデータが見つからない場合に発生します。

よくある原因は以下です。

  • columns.dataで指定したプロパティ名が間違っている
  • Ajaxのレスポンスに対象の項目が存在しない
  • 値がnullまたはundefinedになっている
  • columns.renderで値を返していない
  • HTMLテーブルの列数が合っていない

たとえば、レスポンスが以下だとします。

const users = [
    {
        userName: '山田 太郎',
        email: 'yamada@example.com'
    }
];

このとき、columns.dataに存在しないnameを指定すると警告が出ます。

new DataTable('#usersTable', {
    data: users,
    columns: [
        { data: 'name', title: '名前' },
        { data: 'email', title: 'メール' }
    ]
});

修正方法

実際のデータに合わせてcolumns.dataを修正します。

new DataTable('#usersTable', {
    data: users,
    columns: [
        { data: 'userName', title: '名前' },
        { data: 'email', title: 'メール' }
    ]
});

値がない場合に空文字や固定文言を表示したい場合は、defaultContentを使うと警告を避けられます。

new DataTable('#usersTable', {
    data: users,
    columns: [
        {
            data: 'userName',
            title: '名前',
            defaultContent: ''
        },
        {
            data: 'email',
            title: 'メール',
            defaultContent: '未設定'
        }
    ]
});

renderを使う場合は、どのtypeで呼び出されても値を返すようにします。

{
    data: 'status',
    title: 'ステータス',
    render: function (data, type) {
        if (type === 'display') {
            return data === 'active' ? '有効' : '停止';
        }

        return data;
    }
}

displayのときだけreturnして、それ以外のときにundefinedになる実装は避けましょう。

Incorrect column count

以下のような警告です。

DataTables warning: table id=usersTable - Incorrect column count.

theadで定義している列数と、tbodyで使っている列数が一致していない場合に発生します。

<table id="usersTable">
    <thead>
        <tr>
            <th>名前</th>
            <th>メール</th>
            <th>ステータス</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>山田 太郎</td>
            <td>yamada@example.com</td>
        </tr>
    </tbody>
</table>

この例では、ヘッダーは3列ですが、ボディは2列しかありません。

修正方法

theadtbodyの列数をそろえます。

<table id="usersTable">
    <thead>
        <tr>
            <th>名前</th>
            <th>メール</th>
            <th>ステータス</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>山田 太郎</td>
            <td>yamada@example.com</td>
            <td>有効</td>
        </tr>
    </tbody>
</table>

DataTablesでは、tbody内でcolspanrowspanを使うと列数の計算が合わず、エラーの原因になることがあります。
一覧表示に使う行は、基本的にすべて同じ列数にしておくのが安全です。

Ajax error

以下のような警告です。

DataTables warning: table id=usersTable - Ajax error.

DataTablesのajaxオプションでデータを取得しているとき、サーバーが正常なHTTP 2xxレスポンスを返さない場合に発生します。

よくある原因は以下です。

  • APIのURLが間違っている
  • サーバー側で500エラーが発生している
  • 認証が必要なAPIに未ログインでアクセスしている
  • CSRFトークンが不足している
  • CORSでブロックされている

確認方法

ブラウザの開発者ツールでNetworkタブを開き、DataTablesが呼び出しているリクエストを確認します。

確認するポイントは以下です。

  • ステータスコードが200になっているか
  • リクエストURLが正しいか
  • レスポンス本文にエラーメッセージが出ていないか
  • 認証やCSRFトークンが必要なAPIではないか

修正例

CSRFトークンが必要なAPIであれば、Ajaxリクエストにヘッダーを追加します。

new DataTable('#usersTable', {
    ajax: {
        url: '/api/users',
        headers: {
            'X-CSRF-Token': csrfToken
        }
    },
    columns: [
        { data: 'name', title: '名前' },
        { data: 'email', title: 'メール' }
    ]
});

API側で例外が出ている場合は、DataTablesの設定だけでは直りません。
サーバーログを確認し、APIが正常にJSONを返しているかを確認します。

Invalid JSON response

以下のような警告です。

DataTables warning: table id=usersTable - Invalid JSON response.

Ajaxのレスポンスは返ってきているものの、DataTablesが期待するJSONとして解釈できない場合に発生します。

よくある例は以下です。

  • APIがHTMLのエラーページを返している
  • ログイン画面のHTMLが返っている
  • PHPのWarningやNoticeがJSONの前後に出力されている
  • JSONの形式が壊れている
  • dataSrcの指定とレスポンス構造が合っていない

修正方法

まずNetworkタブでレスポンス本文を確認します。

DataTablesが配列を直接受け取るなら、以下のようなJSONが返る必要があります。

[
    {
        "name": "山田 太郎",
        "email": "yamada@example.com"
    }
]

レスポンスがdataプロパティの中に入っている場合は、dataSrcを指定します。

{
    "data": [
        {
            "name": "山田 太郎",
            "email": "yamada@example.com"
        }
    ]
}
new DataTable('#usersTable', {
    ajax: {
        url: '/api/users',
        dataSrc: 'data'
    },
    columns: [
        { data: 'name', title: '名前' },
        { data: 'email', title: 'メール' }
    ]
});

APIがログイン画面やエラーページを返している場合は、DataTablesではなくAPI側の認証やエラー処理を修正します。

Non-table node initialisation

以下のような警告です。

DataTables warning: Non-table node initialisation (div).

DataTablesはtable要素に対して初期化するライブラリです。
divなど、table以外の要素を指定するとこの警告が出ます。

<div id="usersTable">
    <table>
        ...
    </table>
</div>
new DataTable('#usersTable');

この場合、#usersTabledivなのでエラーになります。

修正方法

table要素にIDやクラスを付けて、そこを指定します。

<div>
    <table id="usersTable">
        ...
    </table>
</div>
new DataTable('#usersTable');

クラスでまとめて初期化する場合も、対象がtableだけになるようにします。

document.querySelectorAll('table.js-data-table').forEach((table) => {
    new DataTable(table);
});

DataTable is not defined

以下のようなJavaScriptエラーです。

Uncaught ReferenceError: DataTable is not defined

DataTables本体のJavaScriptが読み込まれていない、または読み込み前に初期化コードを実行している場合に発生します。

修正方法

DataTablesのJavaScriptを読み込んだあとに初期化します。

<link rel="stylesheet" href="https://cdn.datatables.net/2.3.8/css/dataTables.dataTables.min.css">

<table id="usersTable">
    ...
</table>

<script src="https://cdn.datatables.net/2.3.8/js/dataTables.min.js"></script>
<script>
    new DataTable('#usersTable');
</script>

初期化コードを別ファイルにしている場合も、読み込み順に注意します。

<script src="https://cdn.datatables.net/2.3.8/js/dataTables.min.js"></script>
<script src="/js/users-table.js"></script>

$(…).DataTable is not a function

以下のようなJavaScriptエラーです。

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

jQuery形式で初期化しているのに、jQueryまたはDataTablesのjQuery連携が正しく読み込まれていない場合に発生します。

$('#usersTable').DataTable();

修正方法

jQuery形式で書く場合は、jQueryを先に読み込み、そのあとにDataTablesを読み込みます。

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<script src="https://cdn.datatables.net/2.3.8/js/dataTables.min.js"></script>
<script>
    $('#usersTable').DataTable();
</script>

DataTables 2系では、jQueryを使わずに以下のようにも書けます。

new DataTable('#usersTable');

プロジェクト内でjQuery形式と非jQuery形式が混ざると読み込み順の問題を見落としやすいので、どちらの書き方で統一するかを決めておくと扱いやすくなります。

i18n file loading error

以下のような警告です。

i18n file loading error

language.urlで日本語化ファイルなどの外部JSONを読み込んでいるとき、そのファイルの取得に失敗すると発生します。

new DataTable('#usersTable', {
    language: {
        url: '/i18n/ja.json'
    }
});

よくある原因は以下です。

  • URLが間違っている
  • JSONファイルが存在しない
  • JSONの形式が壊れている
  • CORSでブロックされている
  • サーバーがHTMLの404ページを返している

修正方法

Networkタブでja.jsonなどのリクエストを確認します。
ステータスコードが200で、レスポンス本文が正しいJSONになっているかを見ます。

外部ファイルの読み込みで詰まりやすい場合は、languageオプションに直接日本語文言を書いておく方法もあります。

new DataTable('#usersTable', {
    language: {
        search: '検索:',
        lengthMenu: '_MENU_件ずつ表示',
        info: '_TOTAL_件中 _START_ から _END_ まで表示',
        zeroRecords: '一致するデータがありません',
        paginate: {
            previous: '前へ',
            next: '次へ'
        }
    }
});

エラー調査の流れ

DataTablesのエラーは、以下の順番で見ると切り分けしやすいです。

  1. コンソールのエラー文を読む
  2. エラーに出ているtable idを確認する
  3. theadtbodycolumnsの列数を確認する
  4. Ajaxを使っている場合はNetworkタブでレスポンスを確認する
  5. columns.dataと実際のレスポンス項目名を比較する
  6. 初期化が複数回実行されていないか確認する
  7. JavaScriptとCSSの読み込み順を確認する

特に、以下の2つは頻出です。

  • Requested unknown parameterは、列定義とデータの形が合っていない
  • Invalid JSON responseAjax errorは、APIレスポンスをNetworkタブで見る

エラー文だけで悩むより、DataTablesがどのテーブルに対して、どのデータを取りに行っているのかを確認すると原因に近づきやすくなります。

まとめ

DataTablesのエラーは、メッセージごとに見る場所を決めておくと追いやすくなります。

  • 初期化を2回している場合はCannot reinitialise DataTable
  • 列定義とデータが合っていない場合はRequested unknown parameter
  • ヘッダーとボディの列数が違う場合はIncorrect column count
  • APIが2xx以外を返している場合はAjax error
  • APIのレスポンスがJSONではない場合はInvalid JSON response
  • table以外を初期化している場合はNon-table node initialisation
  • 読み込み順が違う場合はDataTable is not defined$(...).DataTable is not a function

DataTablesはエラー文にtable idや対象のパラメータ名を出してくれることが多いです。
まずはその情報を手がかりに、HTML、JavaScript、Ajaxレスポンスの順で確認していくと、原因を見つけやすくなります。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

目次