0

I want to display the values in my Datatable. I opened my chrome dev tool and go to network tab, XHR and the problem is, the response is an HTML document

server side code:

router.get('/agents', (req, res) => {
  let dB = req.dB;
  let sql = 'SELECT * FROM tbl_users WHERE role_id = 3';

  dB.query(sql, (err, agents) => {
    if (err) throw err;
    const data = { agents };
    console.log(data);

    res.render('dashboard/agents', data);
  });
});

client side script:

$('#agent_table').DataTable( {
  processing: true,
  serverSide: true,
  ajax: {
    url: '/administrator/agents',
    type: 'GET',
    dataSrc: 'agents'
  },
  columns: [
    { data: 'user_id' },
    { data: 'checked' },
    { data: 'first_name' },
    { data: 'middle_name' },
    { data: 'role_id' },
  ]
} );

client side htmlt:

<table id="agent_table" class="table table-striped table-bordered dt-responsive nowrap"
            cellspacing="0" width="100%">
            <thead>
              <tr>
                <th>User ID</th>
                <th>
                  <div class="checkbox checkbox-success select_all">
                    <input class="styled" type="checkbox" id="check_all">
                    <label for="check_all" class="check_all_label">All</label>
                  </div>
                </th>
                <th>First Name</th>
                <th>Middle Name</th>
                <th>Last Name</th>
                <th>Role</th>
              </tr>
            </thead>
          </table>

console log in server

{ agents: [ RowDataPacket { user_id: 6, first_name: 'Pamela', middle_name: 'Pearl', last_name: 'Sabes', email: '[email protected]', password: '1bd07c9db7ae63c02f2ee75471727f58', mobile_number: '09503713607', invite_code: '', birthday: 'Nov 29, 2005', gender: 'Female', address: '', image: null, contact_person: '', contact_person_number: '', role_id: 3, longitude: '', latitude: '', medical_info: '', is_verified: 1, is_deleted: 0, created_at: '0000-00-00 00:00:00', updated_at: 2018-05-30T20:42:43.000Z } ] }

0

3 Answers 3

2

I think the problem is your usage of the res.render. Because according to express documentation res.render() function compiles your template, inserts locals there, and creates html output out of those two things and send it. So instead try this. res.json(data)

Sign up to request clarification or add additional context in comments.

1 Comment

Having exact same problem. Did you solved it? Regards,
0

var url = req.protocol + '://' + req.get('host');

var draw = req.body.draw;
var row = req.body.start;
var count = 1+parseInt(row);
var rowperpage = req.body.length; // Rows display per page
//var columnIndex = req.query.order[0]['column']; // Column index
//console.log(req.body.search);
var dataArr = [];

adminTagModel.CountTagsAll(dataArr, function (totalRecordsValid)
{
    var tagDataobj = {
        row : row,
        rowperpage : rowperpage
    };
    adminTagModel.showTagsAll(tagDataobj, function (totalValid)
    {
        for (var i = 0; i < totalValid.length; i++) 
        {
            dataArr.push({  'count' : count++ ,'tag_name' : totalValid[i].tag_name,'action' : "<a href='"
                +url+"/admin/tagdetails/"+totalValid[i].t_id+"' target='_blank'  ><i class='fa fa-eye'  alt='View Detail'></i></a>"});
        }

        var response = {
            "draw" : draw,
            "iTotalRecords" : totalRecordsValid[0].allcount,
            "iTotalDisplayRecords" : totalRecordsValid[0].allcount,
            "aaData" : dataArr
        };
        res.send(response);
        return response;
    });

Comments

0

I've recently developed a lightweight library to streamline server-side processing of jQuery Datatables in Node.js. It offers support for both MySQL and Sequelize :)

Library Code

    class SSP {

    static getData(request, userSqlQuery, columns) {
        this.request = request.body;

        this.userSqlQuery = userSqlQuery;

        this.columns = columns;
        this.replacements = {};
        this.whereString = '';

        this.orderData = this.order();
        this.limitData = this.limit();

        this.dbcolumns = this.pluck(this.columns, 'db');

        this.selectColumns = (this.dbcolumns).map((e, i) => {
            return "`" + e + "`";
        }).join(',');


        return this;
    }


    static async sequelize(connection) {
        let finalRecord = {};

        this.filter('sequelize');

        let finalQuery = `SELECT SQL_CALC_FOUND_ROWS ${this.selectColumns} FROM (${this.userSqlQuery}) as temp ${this.whereString} ${this.orderData} ${this.limitData}`;

        try {
            const dbData = await connection.query(
                finalQuery,
                {
                    replacements: this.replacements,
                    type: connection.QueryTypes.SELECT
                }
            );

            const resFilterLength = (await connection.query('SELECT FOUND_ROWS()', {
                type: connection.QueryTypes.SELECT
            }));

            const recordsFiltered = resFilterLength[0]['FOUND_ROWS()'] ?? 0;

            const resTotalLength = await connection.query(`SELECT COUNT(*) as datatable_ssp_count FROM (${this.userSqlQuery}) AS temp`, {
                type: connection.QueryTypes.SELECT
            });

            const recordsTotal = resTotalLength[0]['datatable_ssp_count'] ?? 0;

            finalRecord.draw = parseInt(this.request.draw);
            finalRecord.recordsTotal = parseInt(recordsTotal);
            finalRecord.recordsFiltered = parseInt(recordsFiltered);

            const mappedData = await this.mapDbToDToColumn(this.columns, dbData);

            finalRecord.data = mappedData;

            return finalRecord;

        } catch (error) {
            console.error("Error in sequelize:", error);
            return null;
        }
    }

    static async mysql(connection) {
        let finalRecord = {};

        this.filter('mysql');

        let finalQuery = `SELECT SQL_CALC_FOUND_ROWS ${this.selectColumns} FROM (${this.userSqlQuery}) as temp ${this.whereString} ${this.orderData} ${this.limitData}`;

        try {
            const [dbData, fields] = await connection.query(finalQuery, this.replacements);
            const [resFilterLength, resFilterLengthfields] = await connection.query("SELECT FOUND_ROWS()");
            const recordsFiltered = resFilterLength[0]['FOUND_ROWS()'] ?? 0;
            const resTotalLength = await connection.query(`SELECT COUNT(*) as datatable_ssp_count FROM (${this.userSqlQuery}) AS temp`);
            const recordsTotal = resTotalLength[0][0].datatable_ssp_count ?? 0;

            finalRecord.draw = parseInt(this.request.draw);
            finalRecord.recordsTotal = parseInt(recordsTotal);
            finalRecord.recordsFiltered = parseInt(recordsFiltered);

            const mappedData = await this.mapDbToDToColumn(this.columns, dbData);

            finalRecord.data = mappedData;

            return finalRecord;

        } catch (error) {
            console.error("Error in Mysql:", error);
            return null;
        }

    }

    static async mapDbToDToColumn(columns, data) {
        var out = [];

        for (var i = 0, ien = data.length; i < ien; i++) {
            var row = {};

            for (var j = 0, jen = columns.length; j < jen; j++) {
                var column = columns[j];

                if (typeof column.formatter === 'function') {
                    var formatterResult = column.formatter(data[i][column.db], data[i]) || null;
                    if (formatterResult instanceof Promise) {
                        if (column.dt !== undefined) {
                            row[column.dt] = await formatterResult || null;
                        } else {
                            row[column.db] = await formatterResult || null;
                        }
                    } else {
                        if (column.dt !== undefined) {
                            row[column.dt] = formatterResult;
                        } else {
                            row[column.db] = formatterResult;
                        }
                    }
                } else {
                    if (column.dt !== undefined) {
                        row[column.dt] = data[i][columns[j].db];
                    } else {
                        row[column.db] = data[i][columns[j].db];
                    }
                }
            }
            out.push(row);
        }
        return out;
    }

    static filter(mode) {

        let request = this.request;
        let columns = this.columns;

        let globalSearch = [];

        let columnSearch = [];

        let dtColumns = columns.map(column => column.dt);

        if (mode === 'mysql') {
            this.replacements = [];
        }

        if (request.search && request.search.value !== '') {
            let str = request.search.value;

            for (let i = 0; i < request.columns.length; i++) {
                let requestColumn = request.columns[i];
                let columnIdx = dtColumns.indexOf(requestColumn.data);
                columnIdx = (columnIdx <= -1) ? 0 : columnIdx;
                
                let column = columns[columnIdx];

                if (requestColumn.searchable === 'true' || requestColumn.searchable === true) {

                    if (mode === 'sequelize') {
                        let binding = `ssp_search_value_${i}`;
                        globalSearch.push("`" + column.db + "` LIKE :" + binding);
                        this.replacements[binding] = `%${str}%`;
                    } else if (mode === 'mysql') {
                        globalSearch.push("`" + column.db + "` LIKE ?");
                        (this.replacements).push(`%${str}%`);
                    }
                }
            }
        }

        // Individual column filtering
        for (let i = 0; i < request.columns.length; i++) {
            let requestColumn = request.columns[i];
            let columnIdx = dtColumns.indexOf(requestColumn.data);

            columnIdx = (columnIdx <= -1) ? 0 : columnIdx;

            let column = columns[columnIdx];
            let str = requestColumn.search.value;

            if ((requestColumn.searchable === 'true' || requestColumn.searchable === true) && str !== '') {
                if (mode === 'sequelize') {
                    let binding2 = `ssp_search_value2_${i}`;
                    columnSearch.push("`" + column.db + "` LIKE :" + binding2);
                    let dynamicBindings2 = [];
                    dynamicBindings2.push({
                        key: binding2,
                        value: `%${str}%`
                    })
                } else if (mode === 'mysql') {
                    columnSearch.push("`" + column.db + "` LIKE ?");
                    this.replacements.push(`%${str}%`);
                }
            }
        }

        this.whereString = '';

        if (globalSearch.length > 0) {
            this.whereString = '(' + globalSearch.join(' OR ') + ')';
        }

        if (columnSearch.length > 0) {
            this.whereString = this.whereString === '' ?
                columnSearch.join(' AND ') :
                this.whereString + ' AND ' + columnSearch.join(' AND ');
        }

        if (this.whereString !== '') {
            this.whereString = 'WHERE ' + this.whereString;
        }

    }

    static order() {
        let columns = this.columns;
        let order = '';
        let request = this.request;
        if (request.order && request.order.length > 0) {
            let orderBy = [];
            let dtColumns = columns.map(column => (column.dt ?? column.db));

            for (let i = 0, ien = request.order.length; i < ien; i++) {
                // Convert the column index into the column data property
                let columnIdx = parseInt(request.order[i].column);
                let requestColumn = request.columns[columnIdx];
                columnIdx = dtColumns.indexOf(requestColumn.data);
                let column = columns[columnIdx];

                if (requestColumn.orderable === 'true' || requestColumn.orderable === true) {
                    let dir = request.order[i].dir === 'asc' ? 'ASC' : 'DESC';

                    orderBy.push('`' + column.db + '` ' + dir);
                }
            }

            order = 'ORDER BY ' + orderBy.join(', ');
        }

        return order;
    }

    static limit() {

        let start = this.request.start ?? 0;
        let length = this.request.length ?? 0;
        let limit = '';

        if (start !== undefined && length != -1) {
            limit = "LIMIT " + parseInt(start) + ", " + parseInt(length);
        }
        return limit;
    }

    static pluck(arrayOfObjects, key) {
        return arrayOfObjects.map(obj => obj[key]);
    }
}

export default SSP;

Usage In Controller

import { mysqlConn, sequelize } from '../config/database.js';

class UserController {

    // Usage in Controller
    async listdata(req, res) {
        let column = [  //column to select database columns
            {
                'db': 'name', // column name in database
                'dt': 'name', // column name in datatable
                'formatter': function (data, rowData) {  // (For data formatting )optional
                    return `${data} (${rowData.email})`; // example
                }
            },
            {
                'db': 'email',
                'dt': 'email',

            },
            {
                'db': 'id',
            }
        ];

        let resultSequelize = await (SSP.getData(req, 'select * from users', column)).sequelize(sequelizeConn); // sequelizeConn is sequelize connection instance

        // OR

        let resultMysql = await (SSP.getData(req, 'select * from users', column)).mysql(mysqlConn); // sequelizeConn is mysql connection instance
        res.status(200).json(result);
    }
}

View File

<div class="container">
    <table id="usersTable" class="display" style="width:100%">
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Email</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
</div>

<script>
    $('#usersTable').DataTable({
        "lengthMenu": [[5, 25, 50, -1], [5, 25, 50, "All"]],
        processing: true,
        serverSide: true,
        ajax: {
            url: '/list',
            type: 'post',
        },
        columns: [
            { data: 'id' },
            { data: 'name' },
            { data: 'email' },
        ]
    });
</script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.