javascript – 'Load more' button duplicates or doesn't work AJAX/JSON

Question:

Oops guys, all right?

Next, I have a table that is fed with content from an external JSON file (created from PHP with data coming from the DB). When opening the website, the table comes with only 2 records and by clicking on 'Load more' 2 more records are added to the table.

The way I sort the array is through the unique DB ID, so if there is a record deletion, it gets leaked (ex: 0|1|3|6|7|8) which makes the 'load more' not function or duplicate the data.

I did a fix, but I need to create a new ID in JSON to sort everything again, keeping the count constant. So I would like to know how to optimize or fix my code to work WITHOUT the fix, that is, using the ID, in ascending order, even if it is not sequential, as in the example above.

This is my jQuery code:

$(document).ready(function() {
    var url = "data/results.json";

    $.getJSON(url, function (response){
        $.each (response, function (index, table) {
            loopTable(index <= 1, index, table);
        }); //end each
    }); //end getJSON

    function loopTable(test, index, table){
        var write;
        if(test){

            write += '<tr class="count">';
            write += '<td>' + table.name + '</td>';
            write += '<td>' + table.data + '</td>';
            if (table.status === true) {
                write += '<td class="ap">Aprovado</td>'; 
            } else {
                write += '<td class="ng">Negado</td>';
            }
            write += '<td>' + table.id + '</td>';
            write += '<td><button class="bt_delete">Deletar</button></td>';
            write += '</tr>';

            $('#mytable').append(write);
        }
    }; //end function       

    $('.more').on('click', function(event){
        event.preventDefault();
        var galleryLength = $('.count').length;
        $.ajax(url, {
            cache: false,
            success: function(data){
                if(data){
                    var jsonLength = data.length; 
                }
                $.each(data, function(index, table){
                    loopTable(table.id >= galleryLength && table.id < galleryLength + 2, index, table);
                    if ( table.id.length == galleryLength ) {
                        $('.more').hide();
                    };
                });
            },
            error:  function(){
                $('#myerro').append('<h3>Desculpe, houve um problema.</h3>');
            },
            beforeSend: function(){
                $('.more').hide();
                $('.spinner').fadeIn();
            },
            complete: function(){
                $('.spinner').hide();
                $('.more').fadeIn();
            }
        }); //end ajax
    }); //end click
}); //end ready

Answer:

Assuming the id s that are in the JSON that comes from PHP are in ascending order (which makes more sense), I think you need to track down which id was last loaded. It's also good to work around to ensure that the loopTable reads only two records. For this:

  1. Adicione uma variável, lastId:

    $(document).ready(function() {
        var url = "data/results.json";
        var lastId = -1;
    
  2. Retire o teste do loopTable e rastreie o lastId lá. Também é importante inicializar a variável write adequadamente:

        function loopTable(index, table){
            var write = '';
            write += '<tr class="count">';
            write += '<td>' + table.name + '</td>';
            write += '<td>' + table.data + '</td>';
            if (table.status === true) {
                write += '<td class="ap">Aprovado</td>'; 
            } else {
                write += '<td class="ng">Negado</td>';
            }
            write += '<td>' + table.id + '</td>';
            write += '<td><button class="bt_delete">Deletar</button></td>';
            write += '</tr>';
    
            $('#mytable').append(write);
            lastId = table.id;
        }; //end function
    
  3. Temos que garantir que quando o loopTable for chamado pela primeira vez, que ele vá ler os dois primeiros registros, não importando quais forem os ids, afinal tem que funcionar mesmo se os elementos com ids 0 e 1 tiverem sido removidos:

        $.getJSON(url, function (response) {
            var carregados = 0;
            $.each (response, function (index, table) {
                loopTable(index, table);
                carregados++;
                if (carregados == 2) return false;
            }); //end each
        }); //end getJSON
    
  4. Não use o galleryLength. Ao invés disso, use o lastId:

        $('.more').on('click', function(event){
            event.preventDefault();
            $.ajax(url, {
    
                    var lastLoaded = lastId;
                    var carregados = 0;
                    $.each(data, function(index, table) {
                        if (table.id <= lastLoaded) return true;
                        loopTable(index, table);
                        carregados++;
                        if (carregados == 2) return false;
                    });
    
  5. Acho que este trecho está errado, e nem deveria estar ali, pelo menos não vejo sentido dele estar dentro do $.each(...):

                        if ( table.id.length == galleryLength ) {
                            $('.more').hide();
                        };
    

Furthermore, there is an important observation to be made. PHP is bringing in all the records, converting them all to JSON, everything is being transmitted over the network/internet and javascript is receiving all of that and only then filtering. It would be much better if you do the filtering on the PHP side, where you would AJAX send the id of the last loaded record and the number of records to load, and then PHP would only send the requested records.

Scroll to Top