Solucionado (ver solução)
Solucionado
(ver solução)
3
respostas

Estou recebendo r.fn.init[0] ao tentar acessar um elemento no DOM

Tudo bom?

Estou um requisição e tratando a resposta de um json e usando essa resposta para criar LIs em uma lista.

$.getJSON("www.exemplo.com/json.php", function(data){
  for (let i = 0; i < data.length; i++) {
    $('#minha-ul').append(`<li class="minha-li" id="minha-li-${data[i]['id']}">${data[i]['nome']}</li>`);
  }
});

Isso funciona sem problemas.

O problema acontece quando tento acessar um elemento qualquer dessa lista, com o seletor (classe) '.minha-li'. Todas as lis tem essa classe.

Ao colocar um console.log($('.minha-li'));, o console retorna r.fn.init(0).

Fiz esse código de exemplo, que da o mesmo problema. (quando uso um json pequeno, de uns 10 elementos, funciona normalmente).

<html>
  <head>
    <meta charset="utf-8">
    <title>teste</title>
  </head>
  <body>
    <h1>Um titulo qualquer</h1>
    <ul id="minha-ul">
      <!-- As LIs serão criadas via jQuery -->
    </ul>

    <script src="js/jquery.js"></script>
    <script>
      $(function(){
        geraLi();
        console.log($('.minha-li'));
      });

      function geraLi(){
        $.getJSON("www.exemplo.com/json.php", function(data){
          for (let i = 0; i < data.length; i++) {
            $('#minha-ul').append(`<li class="minha-li" id="minha-li-${data[i]['id']}">${data[i]['nome']}</li>`);
          }
        });
      }
    </script>
  </body>
</html>

Pelo que li a respeito, estou tentando acessar um elemento antes que ele tenha sido criado no DOM e que a solução seria usar o $(document).ready(function(){...} ou, no jQuery $(function(){}); Contudo, como podem ver no código, eu estou usando e mesmo assim não dá. Acabei resolvendo com um setTimeout, que só pro meu teste resolve, mas ta errado.

Como faço pra "mandar" o script "esperar" o DOM (assumindo que seja isso mesmo).

Muito obrigado.

3 respostas

o $.getJSON é "assíncrono". Você realmente está tentando pegar um elemento que ainda não foi criado.

Isole seu código em uma função, e logo depois do seu "for" (dentro do $getJSON) chame essa nova função

solução!

Fala Leandro, tudo bom?

A resposta do Everson explica bem o problema, um adendo que posso fazer é. Caso queira executar alguma ação após a consulta do $.getJson ter terminado, você pode utilizar o método .done()

$(function(){
    geraLi();
});

function geraLi(){
    $.getJSON("https://api.github.com/users/soutomario/repos", function(data){
        for (let i = 0; i < data.length; i++) {
            $('#minha-ul').append(`<li class="minha-li" id="minha-li-${data[i]['id']}">${data[i]['name']}</li>`);
        }
    })
    .done(function() { /* Aqui ele já executou o código anterior */
        console.log($('.minha-li'));
    });
}

Caso tenha mais alguma dúvida ou queira explorar mais pontos do getJson, aqui você consegue ver tudo certinho e de forma atualizada: http://api.jquery.com/jquery.getjson/

Espero ter ajudado :)

Obrigado ao Everson e ao Mario, consegui acertar e melhorar o código.

Realmente deveria ter checado a documentação.

Muito obrigado.