19
respostas

pesquisa nã está funcionando onde estou errando?

buscarVideo.js

import { conectaApi } from "./conectaApi.js";
import constroiCard from "./mostraVideos.js";

async function buscarVideo(evento) {/*coloquei o evento como parâmetro para executar */
    evento.preventDefault();
    /*quando clicamos no botão ali, às vezes ele redireciona a página, recarrega no caso. Eu não quero que aconteça nada, 
    então vou botar um evento.preventDefault(); dentro da função. */
     
    const dadosDePesquisa = document.querySelector("[data-pesquisa]").value;
    const busca = await conectaApi.buscaVideo(dadosDePesquisa);
/* Com esse data-pesquisa, já conseguimos enviar lá para conectaApi.buscarVideo. Então nos parentes da linha cinco, no lado superior 
esquerdo da tela, vamos colocar o dado de pesquisa. O que eu fiz aqui? Eu botei um data attributes no input de pesquisa, aí eu 
selecionei ele, e depois eu enviei para o conectaApi.buscarVideo, para fazer aquela busca dinâmica, que ele vai enviar o valor e depois
vai substituir na URL para retornar só o item que a gente quer.
Só que falando em valor, eu esqueci de determinar que o dado de pesquisa eu quero somente o valor daquele elemento. Então, ao final do
querySelector, eu vou ter que botar um .value. */

const lista = document.querySelector("[data-lista]");

while (lista.firstChild){
    lista.removeChild(lista.firstChild);
}

busca.forEach(elemento => lista.appendChild(
    constroiCard(elemento.titulo, elemento.descricao, elemento.url, elemento.imagemm)));
}
 
const botaoDePesquisa= document.querySelector("[data-botao-pesquisa]");

botaoDePesquisa.addEventListener("click", evento => buscarVideo(evento))
/*O que eu fiz aqui? Eu selecionei o botão, aí no botão, eu botei aquela lá que eu falo que é o fofoqueiro, que é o ouvinte de eventos,
 que ele fica ali só cuidando para quando acontecer alguma coisa, fazer tal coisa. Aqui no caso, ele está esperando um clique no botão.
  Então eu defini qual que é o qual que é o evento que ele está esperando, que é o ckick, eu fiz uma arrow function, em que eu enviei 
  esse evento do click para a função buscarVideo. */
19 respostas

conectaApi.js

async function listaVideos() {
    const conexao =await fetch("http://localhost:3000/videos");
    const conexaoConvertida = await conexao.json(); /*O que esse método json faz? Ele pega todos aqueles dados em formato de bytes,
    que estávamos recebendo antes e transforma em um json bonito. E lembra que um json, ele parece um objeto? Até que o nome dele em 
    JavaScript é object notation? Na tela, ele transformou em um objeto para conseguirmos ter acesso a todos os valores lá dentro. */
   // console.log(conexaoConvertida); não precisamos mais 
   return conexaoConvertida /*Quando chamar essa função ele vai retornar aquela lista cheia de coisas do db.json para onde for chamada */
}

//cria a funçao cria video
async function criaVideos(titulo, descricao, url, imagem) 
/*Agora precisamos fazer alguns ajustes. Como eu disse, quando botei titulo: título é porque esse segundo título que está sendo 
atribuído, era para recebermos como variável, para fazer isso, vamos lá na linha oito e dentro dos parênteses, vamos botar esses 
valores título, descrição, URL, vírgula imagem.
Agora vamos conseguir enviar para a variável, enviar para a função criarVideo esses valores, e esses valores vão ser atribuídos 
a essas propriedades do body. */
{
    const conexao = await fetch("http://localhost:3000/videos",{
         /*No nosso caso, agora vamos criar uma requisição POST. Mas não para por aí, temos outras coisas para colocar aqui dentro, 
        como bota uma vírgula depois do POST, dá um Enter e vamos vai colocar headers: {} e abre e fecha chaves, porque também 
        vai ter um conjunto de configurações que poderiam ser feitas, mas vamos botar um só, que é "Content-type":application/json". */
        
        method: "POST",
        /*Lembra que quando eu falei que quando fazíamos o fetch, o único parâmetro obrigatório era URL. E se não especificássemos mais
        nada, o método que estávamos usando, a requisição que estávamos fazendo era GET? Para declarar outros tipos de requisições, 
        é assim, vamos colocar várias outras configurações entre chaves. Inclusive, qual que vai ser o tipo de requisição, que é o método. */
       
        headers: {
            "Content-Type": "aplication/json"
            /*O Content-type que está dentro do headers ele serve para especificar que tipo de arquivo que está sendo enviado, ou 
            recebido. Então quando estamos enviando, ou quando estamos recebendo um arquivo de json, especificamos o tipo do conteúdo, 
            que é o Content-type, como application/json. */
        },

        /* tem mais coisa para colocar aqui? Tem. Então depois então do fechamento das chaves do headers, vamos botar uma vírgula, 
        dá um Enter para ficar embaixo, vamos botar body:JSON.stringify({}). Aqui dentro, vamos enviar os dados que queremos cadastrar 
        nesta requisição, que é título, descrição, URL e imagem. Então vamos botar título = título, que vamos receber uma variável 
        chamada título, não declaramos ainda, mas vamos. Depois vírgula embaixo, descricao =. Onde estou falando igual são dois pontos,
        url: url, imagem: imagem. 
        Então, o que estamos fazendo aqui? Estamos enviando um body, que como a tradução diz, ele é o corpo da requisição, e quando 
        colocamos as chaves com essas coisas ali dentro no lado superior esquerdo da tela, estamos enviando um objeto de variáveis, 
        de valores, indiferentes, pode ser um número, pode ser uma letra, estamos enviando um objeto de valor.
        Só que para enviar uma requisição, precisamos enviar uma string. Então esse JSON.stringify ele vai transformar em uma string 
        tudo aquilo ali que a gente estamos enviando. Assim, vai ser possível criar solicitação POST, a requisição POST.*/
        body: JSON.stringify({
            titulo: titulo,
            /*vamos alterar a descricao  - Também, vou ajustar um negócio aqui. Lembra que a descrição ela era tantas mil visualizações.
            Se eu conseguir colocar manualmente esse número de visualizações não faz sentido, porque quando vamos em outras plataformas 
            de compartilhamento de vídeo isso não é do controle do usuário, isso é de acordo com os cliques. Como ainda não vamos 
            implementar uma função que tem um contador, vamos fazer um número tais visualizações.*/
            //descricao: descricao,
            descricao: `${descricao} mil visualizações`,
            url: url,
            imagem: imagem
        })

       
    } );

    const conexaoConvertida = await conexao.json();
    return conexaoConvertida;
}

async function buscaVideo(termodeBusca) {
    const conexao = await fetch (`http://localhost:3000/videos?q=${termodeBusca}`);
    const conexaoConvertida = conexao.json();

    return conexaoConvertida;
}

criaVideo.js

import { conectaApi } from "./conectaApi.js";/*Você está importando a função conectaApi do arquivo conectaApi.js. 
Isso é fundamental para que você possa utilizar as funcionalidades que foram definidas nesse arquivo, como a função que envia os dados
para a API. */

const formulario = document.querySelector("[data-formulario]");

async function criarVideo(evento){/*não função recebe o evento ou seja o que acontece quando eu clico*/
    evento.preventDefault();/*previne que a ação padrão do envio do formulário aconteça */

    const imagem = document.querySelector("[data-imagem]").value;/*value pega o valor do campo que acabamos de selecionar */
    const url = document.querySelector("[data-url]").value;
    const titulo = document.querySelector("[data-titulo]").value;
    const descricao = Math.floor(Math.random() * 10).toString(); /*Agora a questão da descrição, a descrição do nosso vídeo era o número
    de visualizações. Eu até já trouxe a problemática de que isso não poderia ser do controle do usuário, e como não temos um contador 
    a gente precisava definir um número.
    Para isso, vamos criar uma variável chamada descrição do tipo const const descricao = Math.floor(Math.random()*10).toString();.
    O que eu botei tanta coisa com matemática? Não se assuste, usamos map Math.random e ele traz o número aleatório entre zero e um. 
    Para transformar em um número inteiro, fizemos vezes dez, e ele retornou um número inteiro. O Math.floor ele tenta pegar o menor 
    número entre os valores que estiverem dentro do parênteses dele. Nós tendo finalmente um número, transformamos em string para 
    conseguir depois passar para a nossa requisição, não podia ser um número aqui para transformar na frase, precisávamos de uma string.
     */
    console.log(titulo, descricao, url, imagem);
    await conectaApi.criaVideos(titulo, descricao, url, imagem);
/* É importante também avisar que a ordem do que eu coloquei dentro do criarVideo faz sentido, porque se formos no conectaApi é nessa 
ordem que ele está esperando receber, é título, descrição, URL e imagem. Se eu colocasse em outra ordem eu poderia sem querer mandar a
imagem para o campo que ele está esperando uma URL, isso ia dar vários problemas. Então tem que prestar atenção quando estamos enviando
algo para uma função, que também está esperando receber algo. */

window.location.href = "../pages/envio-concluido.html";
/*E para isso, vamos digitar aqui na linha 14, no lado inferior esquerdo da tela, mas dentro da criarVideo depois da await, é window.
location.href = "." e dentro das aspas duplas, vamos colocar o diretório do documento envio-concluido.html. Então para chegar lá vamos
 dar window.location.href = "../pages/envio-concluido.html". Com isso, conseguimos dar um feedback, de tipo conseguiu fazer esse envio,
  e aí ele vai ser enviado para página de envio concluído. */
}

formulario.addEventListener("submit", evento => criarVideo(evento));
/*O que eu fiz? Eu botei como diz a tradução do addEventListener, um ouvinte de ouvinte, é um fofoqueiro. Ele vê quando enviamos o 
formulário, que é quando enviamos o submit daquele formulário e quando isso acontece ele conta a fofoca, ele manda ali o evento, 
o que aconteceu para a função criarVideo. */ 

mostraVideos.js

import { conectaApi } from "./conectaApi.js"; //para acrescentar outras coisas no vídeo da lista que a gente recebeu demos importar

const lista = document.querySelector("[data-lista]")/* Isso que estamos fazendo são data attribute, que servem para individualizar esses
elementos e conseguirmos manipular o DOM através deles. a estrutura padrão é um data, hífen e o nome que você quiser, eu botei data, 
hífen lista, só para ficar bem claro do que nós estamos tratando.*/

export default function constroiCard(titulo, descricao, url, imagem){/**Tendo isso, precisamos começar a construir aqueles li's que tem dentro do elemento de listas. 
    Então para isso, vamos criar uma função chamada constroiCard() {}. Dentro das chaves vamos criar uma variável do tipo constante
    também const video = document.createElemnt("li"). */
    const video = document.createElement("li");

    /*Tendo isso, precisamos começar a construir aqueles li's que tem dentro do elemento de listas. Então para isso, vamos criar uma 
    função chamada constroiCard() {}. Dentro das chaves vamos criar uma variável do tipo constante também 
    const video = document.createElemnt("li"). */
    video.className = "videos_item";
    video.innerHTML = `<iframe width="100%" height="72%" src="${url}"
                title="${titulo}" frameborder="0"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                allowfullscreen></iframe>
            <div class="descricao-video">
                <img src="${imagem}" alt="logo canal alura">
                <h3>${titulo}</h3>
                <p>${descricao}</p>
            </div>`/* Então agora já temos as coisas dinâmicas, a estrutura que estamos botando aqui, ela se chama Template Strings. 
            Conseguimos botar variadas, através da estrutura que é o cifrão, abre e fecha chaves e o nome da variável, e ela se unirá 
            a toda string que estávamos colocando, como se ela já fizesse parte. Na hora que for imprimir elas não vão aparecer como 
            variáveis, elas vão aparecer como parte da string  */
            return video;
}

/*  E eu vou criar outra função para consumir aquelas funções do conectaApi. Então vou criar uma função assíncrona também, 
que vai ser async function listaVideo()dentro dela vou criar outra variável constante, const lista = await conectaApi.listaVídeos();
. Agora ele vai esperar tudo aquilo se resolver e vai retornar para mim a lista, aquela lista de vídeos que temos no db.jason. 
E vamos conseguir usar ela para fazer outras coisas, para criar cards para cada um daqueles itens da lista.*/

async function listaVideo() {/*Agora ele vai esperar receber esses valores, título, descrição, 
URL e imagem e vamos poder usar em outros lugares ali dentro, que vai ser lá dentro do innerHTML. */
    const listaApi= await conectaApi.listaVideos();
    listaApi.forEach(elemento => lista.appendChild(
        constroiCard(elemento.titulo, elemento.descricao, elemento.url, elemento.imagem)));
        /*para cada item da lista da API criou um card, que seria uma li, que foi anexada dentro da ul dentro do index.html, 
        que estamos referenciando como lista. Então fazendo isso estamos criando o que queríamos, a conexão das duas funções, 
        para cada item da lista uma li será criada. */

}

listaVideo();

index.html

<!DOCTYPE html>
<html lang="pt-br">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./css/reset.css">
    <link rel="stylesheet" href="./css/estilos.css">
    <link rel="stylesheet" href="./css/flexbox.css">
    <title>AluraPlay</title>
    <link rel="shortcut icon" href="./img/favicon.ico" type="image/x-icon">
</head>

<body>

    <header>

        <nav class="cabecalho">
            <a class="logo" href="./index.html"></a>

            <div class="cabecalho__pesquisar">

                <input type="search" placeholder="Pesquisar" id="pesquisar" class="pesquisar__input" data-pesquisa>
                <button class="pesquisar__botao" data-botao-pesquisa>

            </div>

            <div class="cabecalho__icones">
                <a href="./pages/enviar-video.html" class="cabecalho__videos"></a>
            </div>
        </nav>

    </header>

    <ul class="videos__container" alt="videos alura" data-lista>
    
        <li class="videos__item">
            <iframe width="100%" height="72%" src="https://www.youtube.com/embed/y8FeZMv37WU"
                title="Conhecendo a linguagem Go | Hipsters.Talks" frameborder="0"
                allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
                allowfullscreen></iframe>
            <div class="descricao-video">
                <img src="./img/logo.png" alt="logo canal alura">
                <h3>Conhecendo a linguagem Go | Hipsters.Talks</h3>
                <p>3 mil visualizações</p>
            </div>
        </li>
    </ul>
    <!--<script src="./JS/conectaApi.js"></script>!-->
    <script src = "./JS/mostraVideos.js" type="module"></script>
    <!--Isso acontece porque quando a gente trabalha com import, export porte para poder usar trechos de código em outro arquivo,
     estamos trabalhando com o modularização, então precisamos declarar que isso está acontecendo, e para fazer isso é só botar um 
     type"module-->

     <script src="./JS/buscarVideo.js" type="module"></script>
</body>

</html>

Ai está meu código alguém da um help porque já li e reli e não consigo localizar o erro.

Oi Alexandre,

Analisando seu código, identifiquei que o problema está na função buscaVideo em conectaApi.js.

A linha const conexaoConvertida = conexao.json(); não está usando await, o que faz com que a função retorne uma Promise pendente em vez dos dados convertidos. 😜

Para corrigir, você precisa adicionar await antes de conexao.json(), assim:

async function buscaVideo(termodeBusca) {
    const conexao = await fetch (`http://localhost:3000/videos?q=${termodeBusca}`);
    const conexaoConvertida = await conexao.json();

    return conexaoConvertida;
}

Com essa alteração, a função buscaVideo retornará os dados corretamente, e a pesquisa funcionará como esperado. 🤔

Para saber mais: Documentação do método fetch(). Este link leva à documentação oficial do método fetch, onde você pode aprender mais sobre como fazer requisições HTTP e lidar com as respostas.

Continue praticando e explorando novas funcionalidades! 🧐

Boa tarde,

Fiz as alterações mesmo assim não funciona ao pesquisar só pisca a tela e não tras o vídeo da palavra pesquisada

Oi Alexandre,

Entendo sua frustração, 😞 mesmo com a correção do await no conectaApi.js, a pesquisa ainda não funciona como esperado.

O problema agora está na forma como você está construindo o card do vídeo na função buscarVideo em buscarVideo.js.

Você está usando elemento.imagemm quando deveria ser elemento.imagem. 🤔

Ajuste a linha no buscarVideo.js:

busca.forEach(elemento => lista.appendChild(
    constroiCard(elemento.titulo, elemento.descricao, elemento.url, elemento.imagem)));

para:

busca.forEach(elemento => lista.appendChild(
    constroiCard(elemento.titulo, elemento.descricao, elemento.url, elemento.imagem)));

Essa pequena correção deve resolver o problema da pesquisa. 👍

Para saber mais: Documentação do método forEach(). Este link leva à documentação oficial do método forEach, onde você pode aprender mais sobre como iterar sobre arrays em JavaScript.

Continue praticando e aprimorando suas habilidades! 🧐

fiz a correção e nada

A tela só pisca e não retorna o vídeo da palavra pesquisada e fica todos os vídeos igual

Oi Alexandre,

Entendo que é frustrante a pesquisa ainda não estar funcionando. 😡

Mesmo após as correções anteriores, o problema pode estar na forma como os dados da busca estão sendo utilizados para construir os cards de vídeo.

Para investigar isso, você pode adicionar um console.log dentro da sua função buscarVideo em buscarVideo.js para verificar o que está sendo retornado da API após a pesquisa.

Adicione esta linha logo após a linha const busca = await conectaApi.buscaVideo(dadosDePesquisa);:

console.log("Dados da busca:", busca);

Abra o console do seu navegador, faça uma pesquisa e veja qual a estrutura dos dados que estão sendo exibidos.

Verifique se os nomes das propriedades (titulo, descricao, url, imagem) correspondem exatamente ao que a sua função constroiCard em mostraVideos.js espera receber.

Uma diferença na nomenclatura pode impedir que os vídeos sejam exibidos corretamente.

Para saber mais: Usando o console do navegador.

A persistência te levará à solução 💪.

Está tudo correto conforme print abaixo mas não funciona a pesquisa ![](Insira aqui a descrição dessa imagem para ajudar na acessibilidade )

Está dificil achar esse erro vou seguir na aula já tentei verificar linha a linha com o código de vocês junto ao Github, arquivo por arquiuvo fiz tudo igual e não funciona.

entrei nesse repositório https://github.com/alura-cursos/aluraplay-requisicoes/tree/aula04 olhei arquivo por arquivo, linha por linha de código e não acho o erro já corrigi alguns salvei e nada funciona no campo de pesquisa ao pesquisar qualquer vídeo só pisca e nada acontece.

coloquei os arquivos no github nesse endereço https://github.com/xandydob/formulario2 dá uma olhada e tenta ver o erro, onde está porque já li e reli e não consigo localizar, por favor alguém me ajuda.

Alexandre

Baixei seu código e a busca funcionou normalmente

pse que luta comigo não está funcionando

Consegue acessar minha máquina remotamente e tentar resolver comigo, pra eu aprender onde está o erro? meu zap 48-996275324

Crie uma reunião no https://meet.google.com/ e envia o link

https://meet.google.com/twf-shwv-mqy

É Alexandre, na sua máquina não está funcionando, nem o código do instrutor

Eu não sei explicar 😞

Tenta abrir um chamado na Central de Ajuda Alura

Boa sorte 🤓