Use AJAX return in other functions

Asked

Viewed 615 times

1

I have 2 functions: A function 1 returns a JSON via AJAX and lists the data in an HTML table dynamically, until then everything works. The function 2 need to manipulate the same data, however, I did not want to make another AJAX request invoking the function 1 again and given that the data is already on the client side. I am currently using a global variable that stores the return of AJAX, so I use it in other functions, but I know that global variable is not a good practice. It is possible to store AJAX return data in a variable without being global and use it in other functions?

Code for function 1:

//Variavel com escopo global para guardar os dados da consulta
//Quando é feito uma requisição AJAX na função listarRegistros
dadosJson = [];
paginaAtual = 0;

//Função para listar registros de qualquer tabela via AJAX
//Passado o NOME da TABELA conforme o que está no bando de dados
function listarRegistros(tabela, form, input, pagina, nomeModal) {

    var qtde = $("#cbo-qtde-registros").val();

    //Abrindo reguisição AJAX e definindo parametros
    $.ajax({
        type: 'POST',
        url: '../file/crud-cad-redes.php?op=lista-all' + '&tabela=' + tabela,
        dataType: 'JSON',
        success: function (dados) {
            if (dados) {
                //Se a consulta retornar os dados é chamado a função para montar a tabela
                dadosJson = dados;//setando variavel global para armazenar os dados de retorno do AJAX
                montaTabela(dados, tabela, pagina, qtde, nomeModal);
                limparInputs();
            } else {
                alert('erro');
            }
        }
    });
    return false;
}

Code for function 2:

//Função para montar tabela com arrays JSON
function montaTabela(dados, tabela, pagina, qtde, nomeModal) {
    //Limpa o body da respectiva tabela
    $('#' + tabela + ' > tbody > tr').remove();
    var tbody = $('#' + tabela + ' > tbody');

    //Chamando a função para listar as colunas da tabela e atribuindo o retorno na variavel
    var arrColunas = listaColunasTabela(tabela);

    //Loop para montar as linhas com cada registro do array JSON da consulta - sistema de paginação
    for (var i = pagina * qtde; i < dados.length && i < (pagina + 1) * qtde; i++) {
        tbody.append(
                //Em cada iteração é chamado a função para montar as colunas da linha
                '<tr>' + montaColunas(dados[i], arrColunas, nomeModal) + '</tr>'
                );
    }

    //Setando valor do input text da navegação da paginação e ajustando os botoes da paginação
    $('#txt-navegacao').val(('Página ' + (pagina + 1) + ' de ' + Math.ceil(dados.length / qtde)));
    ajustarBotoes(pagina, qtde, dados);
}

//Função para montar as colunas e seus atributos de cada linha da tabela
function montaColunas(dados, arrColunas, nomeModal) {
    
    //Recuperando o primeiro elemento do array JSON para saber a
    //A qtde de colunas (cabeçalho da tabela enviado pela consulta SLQ) e
    //Recuperar as keys do elemento (nomes dos cabeçalhos de cada registro)
    var elemento = Object.keys(dados);
    var colunas = '';

    //Loop para montar as colunas - Neste caso do ultimo para o primeiro registro do array JSON
    for (var j = elemento.length - 1; j >= 0; j--) {

        //Loop para iterar o array de colunas da tabela HTML
        for (var k = 0; k < arrColunas.length; k++) {

            //Verifica se nome da classe do array de colunas da tabela HTML é
            //igual ao nome da key do elemento do array JSON da consulta
            //Se for igual a coluna é exibida na tabela, caso contrario e desconsiderada
            if (arrColunas[k] == elemento[j]) {

                //Na posição 0 do loop é chamado a função para montar os dados da respectiva coluna
                if (j == 0) {
                    colunas += montaDadosColuna(dados, elemento, nomeModal) + '</td>';

                    //Nas demais posições é adicionado as colunas HTML e os seus valores normalmente
                } else {
                    colunas += '<td>' + dados[elemento[j]] + '</td>';
                }
            }
        }
    }

    //Retornando o resultado para a função MontaTabela
    return colunas;
}

//Função para montar a coluna com os dados para selecionar posteriormente
function montaDadosColuna(dados, elemento, nomeModal) {
    var coluna = '<td';

    //Loop para inserir os DATAs no respectiva TD da tabela
    for (var i = elemento.length - 1; i >= 0; i--) {

        //É adicionado o DATA + a key do elemento do array JSON
        coluna += ' data-' + elemento[i] + '="' + dados[elemento[i]] + '"';
    }

    //Fechando a tag TD é adicionado um icone com a classe para selecionar o registro na tabela posteriormente
    //Os DATAs são utilizado no momento do click deste icone para preencher o formulario
    coluna += '><img src="../img/btn_modal_05.png" height="20px" style="cursor:pointer" class="btn-seleciona" title="Clique aqui para editar o registro" data-modal="' + nomeModal + '"' + '>';
    return coluna;
}

//Função para listar e armazenar em array os nomes das classes das colunas da respectiva tabela
//A função recupera as classes que estão nas tags 'th' da respectiva tabela
function listaColunasTabela(tabela) {
    var arrColunas = [];

    //Iteração na tag 'th' para empilhar os nomes das classes
    $('#' + tabela + ' > thead th').each(function () {
        arrColunas.push($(this).attr('class'));
    });

    //Retornando o array com as classes das colunas
    return arrColunas;
}

//Função move para ultima pagina da paginação
function moveLast(nomeModal) {
    paginaAtual = Math.floor(dadosJson.length / $("#cbo-qtde-registros").val());
    montaTabela(dadosJson, nomeTabela, paginaAtual, $("#cbo-qtde-registros").val(), nomeModal);
}

//Função move para próxima pagina da paginação
function moveNext(nomeModal) {
    if (paginaAtual < dadosJson.length / $("#cbo-qtde-registros").val() - 1) {
        paginaAtual++;
        montaTabela(dadosJson, nomeTabela, paginaAtual, $("#cbo-qtde-registros").val(), nomeModal);
    }
}

//Função move para pagina anterior da paginação
function movePrevious(nomeModal) {
    if (paginaAtual > 0) {
        paginaAtual--;
        montaTabela(dadosJson, nomeTabela, paginaAtual, $("#cbo-qtde-registros").val(), nomeModal);
    }
}

//Função move para primeira página da paginação
function moveFirst(nomeModal) {
    paginaAtual = 0;
    montaTabela(dadosJson, nomeTabela, paginaAtual, $("#cbo-qtde-registros").val(), nomeModal);
}

//Função para habilitar ou desabilitar os botoes de navegação da paginação
function ajustarBotoes(pagina, qtde, dados) {
    $('#btn-next').prop('disabled', dados.length <= qtde || pagina >= dados.length / qtde - 1);
    $('#btn-previous').prop('disabled', dados.length <= qtde || pagina == 0);
    $('#btn-last').prop('disabled', dados.length <= qtde || pagina >= dados.length / qtde - 1);
    $('#btn-first').prop('disabled', dados.length <= qtde || pagina == 0);
}

  • What is function 2? is montaTabela? where you use dadosJson?

  • Sergio. I’ve entered function 2 now. I’m using the global variable I set in the AJAX request Success, the one I’d like to delete.

  • It’s just these two that use dadosJson?

  • No, there are other functions that use the dataJson as well.However, if I can recover the AJAX value in this function, the others will receive the data as parameter.

  • So you better put in the full code, so we have a better idea. They’re different files or the code is all in one file?

  • Sergio, posted all the functions. Note that there is also another paginate variable as global. This is a pagination system I created for the HTML table. My idea is to create a single manipulate functionPagination() and within it create all the pagination control, but for this I need the data of the ajax request.

  • sessionStorage would not be a good?

  • @Maxrogério, Perfect your suggestion!!! I researched about sessionStorage and managed to solve my problem. Now the code has become much cleaner and no need to use global variables. Thank you very much!

  • Oops! If you need me...

  • Blz... Just a question, I’m new to Stackoverflow, have to mark something as solved in the topic, post the code solved I don’t know?

Show 5 more comments

1 answer

1

Global variables should be avoided as mentioned. Because they can collide with other global names, and because they can be manipulated by someone else’s code.

But often we need variables accessible in different places where it is not possible to have a data flow between pure functions. In such cases the solution may be to make a class, or to create a closed scope.

In your case creating a closed scope solves the problem with fewer changes.

Just put a IIFE around the code you already have, and declare the variable inside. And you must declare with var, let or const and not only nomeDaVariavel = [].

The code would look like this:

(function(){
    var dadosJson = [];
    var paginaAtual = 0;

    // o resto do código aqui dentro

})();
  • Sergio, thanks for the suggestion. I researched about IIFE and even understood the concept of encapsulating the variables in such a function. What I couldn’t understand or implement, is how to access these variables later? Why if I declare this way, other functions do not visualize such variables...

  • @The idea is to have this IIFE around the whole code. As if it were a global, within the IIFE. That is, all the code that needs to access these variables is declared within the IIFE.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.