How to populate a table using a JSON data variable.

How to populate a table using a JSON data variable.

snithfferxsnithfferx Posts: 7Questions: 1Answers: 0

Link to test case:
Debugger code (debug.datatables.net):
Error messages shown:
Description of problem:

Tengo el siguiente problema.
Desde una vista en el navegador llamo mediante AJAX una consulta en el servidor, esta la recibo en formato JSON, para llenar una tabla, la tabla se ha inicializado usando $("#selector).DataTable({options}); pero cuando llega el momento de presentar la respuesta, me dice que no encuentra la función "clear()" y si elimino esta línea, me dice que no encuentra "rows.add()".
No puedo usar la opción o método ajax de la API porque debo rehacer la tabla cuando se haga un cambio o una petición al servidor, y debo cambiar los datos a ser enviados al servidor, sí uso la opción o función "ajax.reload()" me recargaría el dato anterior.
Ejemplo:
Priemra petición:

let collectionsTable = $("#collectionsList").DataTable({
ajax {
      url: '/collections/lista'
}});
respuesta=> collectionsTable = {datos}
Segunda petición:
collectionsTable = $("#collectionsList").DataTable({
ajax {
      url: '/collections/lista?page12'
}});

respuesta=>collectionsTable = {datos de la primera petición}
- Si realizara esto con una variable también resulta de la misma forma; es decir la variable puede cambiar, pero DataTables trae la información antigua; porque para la API la variable no ha cambiado.

Y es por eso que no uso la opción o método "ajax" de la API.
He intentado de varias formas realizar la limpieza de la tabla y luego rellenarla de datos usando "clear", "add" y "draw", pero no encuentra las funciones.
Por cierto, según la documentación, cuando se inicializa una tabla usando "DataTable" debe devolver una instancia de la API, pero sí se usa "dataTable" debe devolver un objeto, hay alguna diferencia entre esto, porque sí uso uno u otro siempre devuelve el mismo objeto.
Uso la versión "1.13.1" del CDN : https://cdn.datatables.net/1.13.1/js/jquery.dataTables.min.js

Object { length: 0, prevObject: {…} }
​
length: 0
​
prevObject: Object { length: 0, prevObject: {} }
​
<prototype>: Object { jquery: "3.6.0", constructor: S(e, t)
, length: 0, … }
​​
DataTable: function DataTable(t)​​
add: function add(e, t)​​
addBack: function addBack(e)​​
addClass: function addClass(t)​​
after: function after()​​
ajaxComplete: function t(e)​​
ajaxError: function t(e)​​
ajaxSend: function t(e)​​
ajaxStart: function t(e)​​
ajaxStop: function t(e)​​
ajaxSuccess: function t(e)​​
alert: function _jQueryInterface(e)​​
animate: function animate(t, e, n, r)​​
append: function append()​​
appendTo: function e(e)​​
attr: function attr(e, t)​​
before: function before()​​
bind: function bind(e, t, n)​​
blur: function n(e, t)​​
button: function _jQueryInterface(e, n)​​
carousel: function _jQueryInterface(e)​​
change: function n(e, t)​​
children: function r(e, t)​​
clearQueue: function clearQueue(e)​​
click: function n(e, t)​​
clone: function clone(e, t)​​
closest: function closest(e, t)​​
collapse: function _jQueryInterface(e)​​
constructor: function S(e, t)​​
contents: function r(e, t)​​
contextmenu: function n(e, t)​​
css: function css(e, t)​​
data: function data(n, e)​​
dataTable: function C(t, v)​​
dataTableExt: Object { buttons: {…}, builder: "-source-", errMode: "alert", … }
​​
dataTableSettings: Array [ {…} ]
​​
dblclick: function n(e, t)​​
delay: function delay(r, e)​​
delegate: function delegate(e, t, n, r)​​
dequeue: function dequeue(e)​​
detach: function detach(e)​​
dropdown: function _jQueryInterface(e)​​
each: function each(e)​​
empty: function empty()​​
emulateTransitionEnd: function emulateTransitionEnd(t)​​
end: function end()​​
eq: function eq(e)​​
even: function even()​​
extend: function extend()​​
fadeIn: function e(e, t, n)​​
fadeOut: function e(e, t, n)​​
fadeTo: function fadeTo(e, t, n, r)​​
fadeToggle: function e(e, t, n)​​
filter: function filter(e)​​
find: function find(e)​​
finish: function finish(a)​​
first: function first()​​
focus: function n(e, t)​​
focusin: function n(e, t)​​
focusout: function n(e, t)​​
get: function get(e)​​
has: function has(e)​​
hasClass: function hasClass(e)​​
height: function o(e, t)​​
hide: function r(e, t, n)​​
hover: function hover(e, t)​​
html: function html(e)​​
index: function index(e)​​
init: function init(e, t, n)​​
innerHeight: function o(e, t)​​
innerWidth: function o(e, t)​​
insertAfter: function e(e)​​
insertBefore: function e(e)​​
is: function is(e)
​​
jquery: "3.6.0"
​​
keydown: function n(e, t)​​
keypress: function n(e, t)​​
keyup: function n(e, t)​​
last: function last()
​​
length: 0
​​
load: function load(e, t, n)​​
map: function map(n)​​
modal: function _jQueryInterface(e, n)​​
mousedown: function n(e, t)​​
mouseenter: function n(e, t)​​
mouseleave: function n(e, t)​​
mousemove: function n(e, t)​​
mouseout: function n(e, t)​​
mouseover: function n(e, t)​​
mouseup: function n(e, t)​​
next: function r(e, t)​​
nextAll: function r(e, t)​​
nextUntil: function r(e, t)​​
not: function not(e)​​
odd: function odd()​​
off: function off(e, t, n)​​
offset: function offset(t)​​
offsetParent: function offsetParent()​​
on: function on(e, t, n, r)​​
one: function one(e, t, n, r)​​
outerHeight: function o(e, t)​​
outerWidth: function o(e, t)​​
parent: function r(e, t)​​
parents: function r(e, t)​​
parentsUntil: function r(e, t)​​
popover: function _jQueryInterface(t)​​
position: function position()​​
prepend: function prepend()​​
prependTo: function e(e)​​
prev: function r(e, t)​​
prevAll: function r(e, t)​​
prevUntil: function r(e, t)​​
promise: function promise(e, t)​​
prop: function prop(e, t)​​
push: function push()
​​
pushStack: function pushStack(e)​​
queue: function queue(t, n)​​
ready: function ready(e)​​
remove: function remove(e)​​
removeAttr: function removeAttr(e)​​
removeClass: function removeClass(t)​​
removeData: function removeData(e)​​
removeProp: function removeProp(e)​​
replaceAll: function e(e)​​
replaceWith: function replaceWith()​​
resize: function n(e, t)​​
scroll: function n(e, t)​​
scrollLeft: function t(e)​​
scrollTop: function t(e)​​
scrollspy: function _jQueryInterface(e)​​
select: function n(e, t)​​
serialize: function serialize()​​
serializeArray: function serializeArray()​​
show: function r(e, t, n)​​
siblings: function r(e, t)​​
slice: function slice()​​
slideDown: function e(e, t, n)​​
slideToggle: function e(e, t, n)​​
slideUp: function e(e, t, n)​​
sort: function sort()
​​
splice: function splice()
​​
stop: function stop(i, e, o)​​
submit: function n(e, t)​​
tab: function _jQueryInterface(e)​​
text: function text(e)​​
toArray: function toArray()​​
toast: function _jQueryInterface(e)​​
toggle: function r(e, t, n)​​
toggleClass: function toggleClass(i, t)​​
tooltip: function _jQueryInterface(e)​​
trigger: function trigger(e, t)​​
triggerHandler: function triggerHandler(e, t)​​
unbind: function unbind(e, t)​​
undelegate: function undelegate(e, t, n)​​
unwrap: function unwrap(e)​​
val: function val(n)​​
width: function o(e, t)​​
wrap: function wrap(t)​​
wrapAll: function wrapAll(e)​​
wrapInner: function wrapInner(n)​​
Symbol(Symbol.iterator): function values()
​​
<prototype>: Object { … }

This question has an accepted answers - jump to answer

Answers

  • kthorngrenkthorngren Posts: 21,135Questions: 26Answers: 4,918
            //Initializing DataTables
            let collectionsTable = $("#collectionsList").DataTable({
                "data": collections,
                "columns": columnas,
                "paging": true,
                "scrollY": 'auto',
                "lengthMenu": lineas(10),
                "searching": true,
                "ordering": true,
                "order": [
                    [2, 'asc']
                ],
                "autoWidth": true,
                "responsive": true,
                "processing" : true,
                "language" : {
                    "url":'dataTables.spanish.json'
                },
                "buttons": botones()
                }).buttons().container().appendTo('#collectionsList_wrapper .col-sm-12:eq(0)');
            //Requesting data
            $.ajax({
                url: '/collections/lista',
                type: 'POST',
                success: function(r) {
                    console.log(collectionsTable);
                    result = JSON.parse(r);
                    collections = result.collections;
                    hasPages(result.pagination);
                    //collectionsTable.clear();
                    collectionsTable.rows.add(collections).draw();
                    if (result.error != undefined) {
                        alertaPopUp(result.error);
                    }
                }
            });
    

    I believe the problem is that language.url is an asynchronous call like ajax. That is if you are having problems with the initial load and getting the not a function error.

        /*function getNewPage (last,cursor,limit) {
            $.ajax({
                url: '/collections/lista',
                type: 'POST',
                data: {
                    page:last,cursor:cursor,limit:limit
                },
                beforeSend:function () {
                    $("#spinger").show();
                },
                success: function(r) {
                    result = JSON.parse(r);
                    collections = result.collections;
                    hasPages(result.pagination);
                    console.log(collectionsTable);
                },
                complete: function () {
                    collectionsTable.clear();
                    collectionsTable.rows.add(collections).draw();
                    $("#spinger").hide();
                }
            });
    

    The collectionsTable is out of context for the function getNewPage. collectionsTable is within the document.ready() function and the getNewPage is outside of this.

    There are two options. The first is to use ajax and use ajax.data as a function to send the parameters:

                data: {
                    page:last,cursor:cursor,limit:limit
                },
    

    Similar to this example. Then use ajax.reload() to fetch the data using the parameters.

    Or if the table structure changes then use destroy() in the getNewPage before the ajax request and reinitialize the datatable in the success function.

    Kevin

  • kthorngrenkthorngren Posts: 21,135Questions: 26Answers: 4,918

    Or if the problem is just with the getNewPage function you can try getting an instance of the API in the function like this:

    function getNewPage (last,cursor,limit) {
        let collectionsTable = $("#collectionsList").DataTable();
        $.ajax({
            url: '/collections/lista',
    ....
    

    Kevin

  • snithfferxsnithfferx Posts: 7Questions: 1Answers: 0

    I understand what you thiink that the problem, but no.
    I have erased the "language" option, but popup the same error message. I attached a screenshot of the error.
    error screenshot

    I have tried initialize the datatable variable out of the "$(document).ready(function() {}" function in order to use the getNewPage() function, but, when a did that the same error jumps out. And if you can see, the "getNewPage()" function is not in use, because "reload" is not working.
    error_screenshot2

    The only way this script works is when a put the initialization inside my $.ajax() request.
    As you can see here:
    working

    But, here come the question, How I repopulate when I get new data? If I fill the variable "collections" and then use "collectionsTable.ajax.reload" as documentation says, is not working properly. because, "reload()" is not a function of "collectionsTable" object, for any reason.
    Also, I have to address that "clear", "rows", "add", and "draw" are not functions of "collectionsTable" object. In other forums I read that is because "dataTable" is not the same as "DataTable" when you use the first ("dataTable") supposly return an object and the second one (DataTable) return an Instance of the API, but for me in both return the same object with the same properties.

  • kthorngrenkthorngren Posts: 21,135Questions: 26Answers: 4,918
    Answer ✓

    I created a test case for you and found the problem.
    https://live.datatables.net/volorena/1/edit

    You are chaining .buttons().container().appendTo('#collectionsList_wrapper .col-sm-12:eq(0)'); to the Datatables initialization. The jQuery appendTo() method returns a jQuery object. collectionsTable is assigned this jQuery object instead of the Datatables API. I removed the chaining and now the Uncaught TypeError: Cannot read properties of undefined (reading 'add') does not appear.

    Kevin

  • snithfferxsnithfferx Posts: 7Questions: 1Answers: 0

    Nice..!
    Works perfectly.
    I correct my code and now show the data as is supposs to do.
    Thanks so much. :)

Sign In or Register to comment.