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

[Dúvida] Erro ao apertar no botão para filtrar

Bom dia,

Ao invés de colocar cada script no HTML, utilizei módulos para exportar as funções (pode ser algo a mais que eu tenha que fazer para funcionar, além do que o instrutor ensinou). Pode ser que eu tenha perdido algo, mas não consegui encontrar o erro, poderiam me ajudar?

Mas a página carrega normalmente e quando clico no botão o seguinte erro é retornado no console:

Uncaught TypeError: livros.filter is not a function at HTMLButtonElement.filtrarLivrosDeFrontCódigo do Filter:

const btnFiltrarLivrosDeFront = document.getElementById('btnFiltrarLivrosFront');
btnFiltrarLivrosDeFront.addEventListener('click', filtrarLivrosDeFront);

export function filtrarLivrosDeFront() {
    let livrosFiltrados = livros.filter(livro => livro.categoria == 'front-end')
    console.table(livrosFiltrados);
}

Código do Main:

import { exibirLivrosNaTela } from "./metodoForEach.js";
import { aplicarDesconto } from "./metodoMap.js";
import { filtrarLivrosDeFront } from "./metodoFilter.js";

let livros = [];
const endpointAPI = 'https://guilhermeonrails.github.io/casadocodigo/livros.json';
getBuscarLivrosAPI();

async function getBuscarLivrosAPI() {
    const res = await fetch(endpointAPI);
    livros = await res.json();

    let livrosComDesconto = aplicarDesconto(livros);

Agradeço desde já a ajuda, o curso está muito bom, instrutor excelente!

3 respostas

Oii, Isabela.

Quero muito te ajudar com sua dúvida, mas para isso, preciso de mais detalhes sobre o que está acontecendo. Assim consigo entender melhor o contexto e sugerir um caminho mais certeiro.

Para facilitar esse processo, recomendo dar uma olhadinha no nosso guia de como fazer uma boa pergunta no fórum. Ele traz algumas dicas rápidas que ajudam bastante na hora de explicar o problema, como compartilhar o código completo no GitHub e mandar aqui.

Quando puder, me manda mais informações? Fico no aguardo para seguir com você nessa.

Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Bom dia,

Segue código no GitHub, conseguem me ajudar na modularização? Acredito que seja algum problema por estar modularizado.

https://github.com/isabelasdeveloper/metodosarray

solução!

Oi, Isabela.

Agradeço por compartilhar seu código completo, assim consegui investigar bem.

Vi que você estruturou bem os arquivos usando módulos — isso é ótimo para manter o código mais organizado e reaproveitável! Agora vamos entender o que estava acontecendo no seu projeto:

O que causava o problema?

O erro inicial (livros.filter is not a function) aparecia porque a função filtrarLivros foi conectada ao clique dos botões, mas ela esperava receber a lista de livros como parâmetro. Só que o addEventListener por padrão não passa esse valor — ele só envia o evento de clique.

Depois que isso foi corrigido, outro ponto importante surgiu: os livros não estavam sendo atualizados na tela ao clicar nos botões. Isso acontecia porque a função exibirLivrosNaTela apenas adicionava os livros com innerHTML +=, sem limpar o conteúdo anterior.

Ajustes:

  1. Encapsulei a chamada do filtrarLivros dentro de uma função anônima, pra garantir que a lista livros fosse passada corretamente:

    botoes.forEach(btn => btn.addEventListener('click', function () {
        filtrarLivros(livros, this);
    }));
    
  2. Alterei a função filtrarLivros pra também receber o botão clicado e usar seu valor como filtro:

    export function filtrarLivros(livros, botao) {
        const categoria = botao.value;
        const livrosFiltrados = livros.filter(livro => livro.categoria === categoria);
        exibirLivrosNaTela(livrosFiltrados);
    }
    
  3. E incluí um innerHTML = '' no início da função exibirLivrosNaTela, para limpar os livros anteriores antes de mostrar os novos:

    inserirLivros.innerHTML = '';
    

Esses pequenos ajustes já fazem toda a diferença para que o filtro funcione direitinho na sua aplicação.

Vou mandar os códigos completos:

main.js

import { exibirLivrosNaTela } from "./metodoForEach.js";
import { aplicarDesconto } from "./metodoMap.js";
import { filtrarLivros } from "./metodoFilter.js";

let livros = [];

const endpointAPI = 'https://guilhermeonrails.github.io/casadocodigo/livros.json';
getBuscarLivrosAPI();

async function getBuscarLivrosAPI() {
    const res = await fetch(endpointAPI);
    livros = await res.json();

    livros = aplicarDesconto(livros);
    exibirLivrosNaTela(livros);

    const botoes = document.querySelectorAll('.btn');
    botoes.forEach(btn => btn.addEventListener('click', function () {
        filtrarLivros(livros, this);
    }));
}

metodoFilter.js

import { exibirLivrosNaTela } from "./metodoForEach.js";

export function filtrarLivros(livros, botao) {
    const categoria = botao.value;
    const livrosFiltrados = livros.filter(livro => livro.categoria === categoria);
    exibirLivrosNaTela(livrosFiltrados);
}

metodoForEach.js

const inserirLivros = document.getElementById('livros');

export function exibirLivrosNaTela(lista) {
    inserirLivros.innerHTML = ''; // limpa antes de adicionar novos livros

    lista.forEach(livro => {
        inserirLivros.innerHTML += `
         <div class="livro">
            <img class="livro__imagens" src="${livro.imagem}" alt="${livro.alt}"/>
            <h2 class="livro__titulo">${livro.titulo}</h2>
            <p class="livro__descricao">${livro.autor}</p>
            <p class="livro__preco" id="preco">R$${livro.preco.toFixed(2)}</p>
            <div class="tags">
                <span class="tag">${livro.categoria}</span>
            </div>
        </div>
        `;
    });
}
Alura Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!