Mudanças entre as edições de "Javascript: consumindo serviços web"

De Aulas
 
(15 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
Afluentes: [[Desenvolvimento Front-end I]], [[Desenvolvimento Front-end II]], [[Usabilidade, desenvolvimento web, mobile e jogos]]
 
  
= Consumindo Serviços Web com JavaScript e JQuery =
 
  
Agora vamos ver como consumir serviços web usando javascript. Pra isso, iremos utilizar uma biblioteca chamada JQuery e, para testes, vamos usar o site [https://www.tvmaze.com tvmaze] de filmes e séries.
+
 
 +
 
 +
 
 +
Afluentes: [[Desenvolvimento Front-end I]], [[Usabilidade, desenvolvimento web, mobile e jogos]].
 +
 
 +
= Consumindo Serviços Web com JavaScript =
 +
 
 +
Veremos aqui como consumir um serviço web da internet usando a função <code>fetch</code> do JavaScript. Para tal, vamos usar o site [https://www.tvmaze.com tvmaze] de filmes e séries. Esse exemplo está o mais simples possível, apenas com HTML sem CSS nem Bootstrap.
 +
 
 +
<center>[[Image:Consumindo_ws_javascript.webp|636x636px]]</center>
 +
 
 +
== index.html ==
  
 
Primeiro vamos criar nosso html. Ele será bastante simples, com um campo de search e uma tabela que será preenchida dinamicamente quando clicarmos no botão de procurar.
 
Primeiro vamos criar nosso html. Ele será bastante simples, com um campo de search e uma tabela que será preenchida dinamicamente quando clicarmos no botão de procurar.
  
<syntaxhighlight lang=html>
+
Veja que aqui temos o <code>tbody</code> com um <code>id</code>. Nesse ponto essa tag se torna importante porque é dentro dela que vamos carregar nossas linhas da tabela. E por meio do id, podemos reconhecer esse elemento facilmente lá do nosso javascript.
 +
 
 +
<syntaxhighlight lang="html">
 
<!DOCTYPE html>
 
<!DOCTYPE html>
<html lang="pt-br">
+
<html>
    <head>
+
<head>
        <!-- Metatag da lingua-->
+
    <script src="tvmaze.js"></script>
        <meta charset="utf-8">
+
    <title>Pesquisa no TVMaze</title>
        <!-- Metatag para página responsiva -->
+
</head>
        <meta name="viewport" content="width=device-width, initial-scale=1">
+
<body>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
+
    <h1>Pesquisa no TVMaze</h1>
        <!-- Bootstrap CSS -->
+
    <form onsubmit="mySubmitHandler(event)">
        <link
+
        <input id="search" type="search">
            href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/css/bootstrap.min.css"
+
        <button type="submit">Pesquisar</button>
            rel="stylesheet"
+
    </form>
            integrity="sha384-BmbxuPwQa2lc/FVzBcNJ7UAyJxM6wuqIj61tLrc4wSX0szH/Ev+nYRRuWlolflfl"
+
    <table class="table">
            crossorigin="anonymous"
+
        <thead>
        >
+
            <tr>
        <!-- Bootstrap Bundle with Popper JavaScript -->
+
                <th>Capa</th>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous"></script>
+
                <th>Nome</th>
        <!-- Fontawesome -->
+
                <th>URL</th>
        <script src="https://kit.fontawesome.com/2c36e9b7b1.js"></script>
+
            </tr>
        <!-- using jquery -->
+
        </thead>
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
+
        <tbody id="movies"></tbody>
        <!-- Nosso script -->
+
    </table>
        <script src="tvmaze.js"></script>
+
</body>
    </head>
+
 
    <body>
 
        <div class="card">
 
            <div class="card-header">
 
                <h5 class="card-title">Consumindo serviços em Javascript</h5>
 
            </div>
 
            <div class="card-body">
 
                <div class="input-group">
 
                    <input
 
                        id="search"
 
                        type="search"
 
                        class="form-control rounded"
 
                        placeholder="Search"
 
                        aria-label="Search"
 
                        aria-describedby="search-addon"
 
                    >
 
                    <button type="button" class="btn btn-outline-primary" onclick="getMovies()">
 
                        <i class="fas fa-search"></i>
 
                    </button>
 
                </div>
 
                <table class="table">
 
                    <thead>
 
                        <tr>
 
                            <th>Capa</th>
 
                            <th>Nome</th>
 
                            <th>URL</th>
 
                        </tr>
 
                    </thead>
 
                    <tbody id="movies"></tbody>
 
                </table>
 
            </div>
 
        </div>
 
    </body>
 
 
</html>
 
</html>
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Agora vamos criar um arquivo javascript com o nome tvmaze.js
+
== tvmaze.js ==
 
 
<syntaxhighlight lang=javascript>
 
function getMovies() {
 
    text = encodeURI($("#search").val());
 
    console.log(text);
 
    $("#movies").empty();
 
    $.ajax({
 
        url: "https://api.tvmaze.com/search/shows?q=" + text,
 
        type: "GET",
 
        dataType: "json",
 
        success: function (data) {
 
            $.each(data, function (index, value) {
 
                var name = value.show.name;
 
                var url = value.show.url;
 
                var img = value.show.image.medium;
 
                addTableRow(img, name, url);
 
            });
 
        }
 
    });
 
}
 
  
function addTableRow(img, name, url) {
+
Agora vamos criar um arquivo javascript com o nome tvmaze.js.
    // Cria uma linha pra tabela
 
    var row = document.createElement("tr");
 
  
    // Cria a célula para a coluna da imagem
+
A função mySubmitHandler<code>()</code> é responsável pela chamada do serviço da tvmaze. Pegamos a informação do campo texto de pesquisa e juntamos com a URL de chamada (ver [https://www.tvmaze.com/api manual da api da tvmaze]). Depois usamos a função <code>fetch()</code> para fazer a chamada ao serviço. Veja que essa função precisa de <code>await</code> por ser assíncrona e a função <code>mySubmitHandler()</code> precisa ser <code>async</code>.
    var td_img = document.createElement("td");
 
    var my_img = document.createElement("img");
 
    my_img.src = img;
 
    my_img.width = 50;
 
    td_img.append(my_img);
 
  
    // Cria a célula para a coluna Nome
+
Agora, '''o que significa que a função é assíncrona?''' Bem, quando estamos carregando nossa página web, os conteúdos estão no nosso site, então tudo será carregado, em geral, na mesma velocidade. Se estamos fazendo uma chamada a um serviço externo, temos a questão de que estamos fazendo uma requisição para outro site, que terá que buscar as informações de um banco de dados e então responder. Esse processo pode levar um tempo.
    var td_name = document.createElement("td");
 
    td_name.innerHTML = name;
 
  
    // Cria a célula paraa  coluna "URL"
+
Se nosso site tiver que esperar esse tempo para terminar de carregar, podemos ter um site meio travado. Então usamos uma função assíncrona para nosso site poder carregar tudo o que precisa e, quando a requisição chegar, apenas atualizamos o site com essas informações que vieram.
    var td_url = document.createElement("td");
 
    var td_url_a = document.createElement("a")
 
    td_url_a.innerHTML = url;
 
    td_url_a.href = url;
 
    td_url.append(td_url_a);
 
  
    // Adiciona as células na linha
+
Dessa forma, o carregamento do site ocorre em paralelo com a busca das informações. Tendo um carregamento de página mais fluída.
    row.append(td_img);
 
    row.append(td_name);
 
    row.append(td_url);
 
  
    // Adiciona a linha na tabela no HTML
+
<syntaxhighlight lang="javascript">
    $("#movies").append(row);
+
// Definimos a URL base
}
+
const tvmaze_link = 'https://api.tvmaze.com';
  
// forma alternativa da função acima
+
// Coloca o cursor no campo de pesquisa quando abre a página
function addTableRowAlternative(img, name, url) {
+
document.addEventListener("DOMContentLoaded", () => {
    $("#movies").append(
+
    const inputField = document.getElementById("search");
        `<tr>
+
     inputField.focus();
            <td><img src="${img}" width=50></td>
+
});
            <td>${name}</td>
 
            <td><a href="${url}">${url}</a></td>
 
        </tr>`
 
     );
 
}
 
</syntaxhighlight>
 
  
= Consumindo Serviços Web com JavaScript e sem JQuery =
+
// Trata o submit do formulário
 +
mySubmitHandler = async (event) => {
 +
    event.preventDefault();
  
Lembrando que o JavaScript é uma linguagem multifacetada, então podemos fazer a mesma coisa de várias formas diferentes, com bibliotecas diferentes, etc.
+
    // criamos a URL e adicionamos o endpoint
 
+
    const url = new URL(tvmaze_link + '/search/shows');
No exemplo acima acabei utilizando JQuery por questão de costume, mas alguns alunos me perguntaram como podoeriamos fazer a mesma coisa sem usar JQuery. Bem, segue abaixo o mesmo exemplo, mas sem o JQuery. Também tirei o Bootstrap pra deixar o HTML o mais simples possível.
 
 
 
== index.html ==
 
  
<syntaxhighlight lang=html>
+
     // Pegamos o parâmetro de pesquisa digitado pelo usuário
<!DOCTYPE html>
+
     const text = document.getElementById("search").value;
<html>
 
     <head>
 
        <script src="tvmaze.js"></script>
 
        <title>Consumindo serviços em Javascript</title>
 
    </head>
 
     <body>
 
        <h1>Consumindo Serviços em JavaScript</h1>
 
        <input id="search" type="search">
 
        <button type="button" onclick="getMovies()">Pesquisar</button>
 
        <table class="table">
 
            <thead>
 
                <tr>
 
                    <th>Capa</th>
 
                    <th>Nome</th>
 
                    <th>URL</th>
 
                </tr>
 
            </thead>
 
            <tbody id="movies"></tbody>
 
        </table>
 
    </body>
 
</html>
 
</syntaxhighlight>
 
  
== tvmaze.js ==
+
    // Adicionamos o parâmetro na busca
 +
    url.search = new URLSearchParams({
 +
        q: text,
 +
    }).toString();
  
<syntaxhighlight lang=javascript>
 
async function getMovies() {
 
    let text = encodeURI(document.getElementById("search").value);
 
    let url = `https://api.tvmaze.com/search/shows?q=${text}`;
 
    let movies = document.getElementById("movies");
 
    movies.innerHTML = "";
 
 
     try {
 
     try {
 +
        // Fazemos a chamada ao serviço web
 
         const response = await fetch(url, {
 
         const response = await fetch(url, {
 
             method: "GET",
 
             method: "GET",
Linha 179: Linha 90:
 
         });
 
         });
 
         const result = await response.json();
 
         const result = await response.json();
 +
        const movies = document.getElementById("movies");
 +
 +
        // Resetamos o conteúdo da tabela
 +
        movies.innerHTML = "";
 +
 +
        // E colocamos o resultado da pesquisa atual
 
         result.forEach(element => {
 
         result.forEach(element => {
             addTableRow(
+
             movies.appendChild(getTableRow(element));
                movies,
 
                element.show.image.medium,
 
                element.show.name,
 
                element.show.url,
 
            );
 
 
         });
 
         });
 
     } catch (error) {
 
     } catch (error) {
Linha 192: Linha 104:
 
}
 
}
  
function addTableRow(parent, img, name, url) {
+
getTableRow = (element) => {
     let tr = document.createElement("tr");
+
     // Criamos uma tag HTML tipo TR
     tr.innerHTML = `
+
    const tr = document.createElement("tr");
         <td><img src="${img}" width=50></td>
+
 
         <td>${name}</td>
+
    // E construímos o conteúdo com as informações do objeto
         <td><a href="${url}">${url}</a></td>`;
+
     tr.innerHTML = (`
     parent.appendChild(tr);
+
         <td>
 +
            <img src="${element.show.image.medium}" width=50>
 +
        </td>
 +
         <td>
 +
            ${element.show.name}
 +
        </td>
 +
         <td>
 +
            <a href="${element.show.url}" target="_blank">
 +
                ${element.show.url}
 +
            </a>
 +
        </td>
 +
    `);
 +
     return tr;
 
}
 
}
</syntaxhighlight>
+
</syntaxhighlight>Como forma opcional, podemos usar a biblioteca [https://jquery.com/ JQuery] também. Segue um exemplo:
 
+
* [[Javascript: consumindo serviços web com JavaScript e JQuery]]
= Exercícios =
 
Esses exercícios são para reforçar o conteúdo aprendido
 
 
 
== Exercício 1 ==
 
* Crie um documento HTML
 
* Coloque um campo texto para digitar um nome
 
* Coloque um botão OK
 
* Ao clicar no botão, abre uma janelinha popup mostrando o nome digitado no campo texto
 
* Faça esse exercício em três versões, usando javascript das três formas: inline, interno e externo
 
 
 
== Exercício 2 ==
 
* Crie um documento HTML
 
* Adicione um título H1 na página com texto vazio
 
* Adicione um campo texto de entrada com ''label'' '''Nome'''
 
* Adicione um botão OK
 
* Quando clicar no botão OK, altere o título H1 para o conteúdo que está no campo texto
 
 
 
== Exercício 3 ==
 
* Copie o código do exercício anteiror
 
* Retire o botão
 
* Altere dinâmicamente o título H1 sempre que o usuário digitar qualquer coisa no campo texto
 
 
 
== Exercício 4 ==
 
 
 
* Crie um código HTML
 
* Crie um campo texto e um botão ENVIAR
 
* crie uma lista (bullets) vazia
 
* Ao clicar no botão ENVIAR, adiciona um ítem na lista com o conteúdo do campo texto e apague o conteúdo do campo texto
 
 
 
== Exercício 5 ==
 
 
 
* Crie um código HTML
 
* Crie três campos de entrada (nome, telefone, e-mail)
 
* Crie dois botões (adicionar, limpar)
 
* Crie uma tabela com três colunas e com os títulos Nome, Telefone e E-mai
 
* Ao entrar com informações nos campos texto e clicar no botão adicionar, é criada uma linha na tabela e são adicionados os dados que estavam nos campos de texto e os campos de texto são limpos
 
* Ao clicar no botão limpar, exclui todas as linhas da tabela, menos a linha de título
 
 
 
== Exercício 6 ==
 
Nesse momento já é provável que vocês já estão criando os próprios serviços na disciplina de Back-end. Dessa forma, gerencie algum serviço de vocês:
 
 
 
* Crie os campos de entrada e ao clicar em um botão, insere as informações no sistema.
 
* Abaixo dos campos de entrada, mostre uma tabela com os dados já existentes no sistema.
 
* Na linha de cada registro, adicione um botão [Excluir] que ao ser clicado, exclui o registro do sistema.
 
 
 
Caso os serviços que vocês estão desenvolvendo seja um pouco complexo, podem fazer algum serviço mais simples ou algum desenvolvido como exercício de aula.
 
 
 
= Desafios =
 
 
 
Os desafios normalmente são exercícios um pouco mais complexos que exigem um pouco mais. O importante não é fazer tudo, é tentar fazer o máximo que puder no seu próprio ritmo. Não tentem copiar da internet ou pedir ajuda ao ChatGPT que daí vocês não aprendem muita coisa. O importante é ver nos manuais, tutoriais, pesquisar, tentar entender o que está fazendo. Lembre-se que no processo de aprendizagem, tudo é mais difícil e são nas dificuldades que aprendemos.
 
 
 
É de maior valor quem faz mais simples, mas entendeu o que fez do que aquela pessoa que copiou ou pediu para alguém fazer por ela.
 
 
 
Essas atividades podem ser desenvolvidas em grupo ou, se preferir, individualmente.
 
 
 
Essas atividades fazem parte de um processo de aprendizagem pelo "aprender fazendo", então vocês podem adicionar mais características ou funcionalidades, mudar o formato, etc.. Deixem a criatividade fluir. Quanto mais vocês fizerem na atividade, mais vão aprender.
 
 
 
== Desafio 1 ==
 
 
 
Desenvolver uma calculadora na WEB usando HTML, CSS e Javascript.
 
* Organize os componentes e botões conforme a imagem abaixo.
 
* Observe que há um histórico dos cálculos já efetuados.
 
* Coloque um botão para alterar o tema das cores: modo diurno e modo noturno.
 
 
 
<center>[[Image:Android_calculadora.png]]</center>
 
 
 
== Desafio 2 ==
 
 
 
Crie um formulário com informações para serem envidadas à um servidor (por exemplo: nome, cpf, idade, telefone, data de nascimento, e-mail, senha e campo para redigitar a senha com um botão de apagar tudo e outro botão para enviar). Mas pensem em uma aplicação específica e com um objetivo certo. Aqui só coloquei um exemplo bastante genérico.
 
 
 
Quando clicar no botão enviar, usando JavaScript, valide o formulário, ou seja, todos os campos do formulário. Todas as questões devem ser obrigatórias. Caso um ou mais campos não esteja ok, mostre onde estão os erros.
 
 
 
Caso o formulário tenha sido validado, mostre, em um campo <code>textarea</code> não editável os dados no formato de string JSON. Esse campo só é criado quando o formulário for validado e enviado.
 
 
 
Usar HTML, CSS e JavaScript (pode usar Bootstrap também). Trabalhe com classes, objetos, eventos, criação de elementos dinâmicos, etc.
 
  
== Desafio 3 ==
+
= Atividade =
  
 
Implemente uma página web que consuma alguma outra API de sua escolha. A API (back-end) pode até ser desenvolvida por você.
 
Implemente uma página web que consuma alguma outra API de sua escolha. A API (back-end) pode até ser desenvolvida por você.

Edição atual tal como às 13h06min de 28 de outubro de 2024



Afluentes: Desenvolvimento Front-end I, Usabilidade, desenvolvimento web, mobile e jogos.

Consumindo Serviços Web com JavaScript

Veremos aqui como consumir um serviço web da internet usando a função fetch do JavaScript. Para tal, vamos usar o site tvmaze de filmes e séries. Esse exemplo está o mais simples possível, apenas com HTML sem CSS nem Bootstrap.

Consumindo ws javascript.webp

index.html

Primeiro vamos criar nosso html. Ele será bastante simples, com um campo de search e uma tabela que será preenchida dinamicamente quando clicarmos no botão de procurar.

Veja que aqui temos o tbody com um id. Nesse ponto essa tag se torna importante porque é dentro dela que vamos carregar nossas linhas da tabela. E por meio do id, podemos reconhecer esse elemento facilmente lá do nosso javascript.

<!DOCTYPE html>
<html>
<head>
    <script src="tvmaze.js"></script>
    <title>Pesquisa no TVMaze</title>
</head>
<body>
    <h1>Pesquisa no TVMaze</h1>
    <form onsubmit="mySubmitHandler(event)">
        <input id="search" type="search">
        <button type="submit">Pesquisar</button>
    </form>
    <table class="table">
        <thead>
            <tr>
                <th>Capa</th>
                <th>Nome</th>
                <th>URL</th>
            </tr>
        </thead>
        <tbody id="movies"></tbody>
    </table>
</body>

</html>

tvmaze.js

Agora vamos criar um arquivo javascript com o nome tvmaze.js.

A função mySubmitHandler() é responsável pela chamada do serviço da tvmaze. Pegamos a informação do campo texto de pesquisa e juntamos com a URL de chamada (ver manual da api da tvmaze). Depois usamos a função fetch() para fazer a chamada ao serviço. Veja que essa função precisa de await por ser assíncrona e a função mySubmitHandler() precisa ser async.

Agora, o que significa que a função é assíncrona? Bem, quando estamos carregando nossa página web, os conteúdos estão no nosso site, então tudo será carregado, em geral, na mesma velocidade. Se estamos fazendo uma chamada a um serviço externo, temos a questão de que estamos fazendo uma requisição para outro site, que terá que buscar as informações de um banco de dados e então responder. Esse processo pode levar um tempo.

Se nosso site tiver que esperar esse tempo para terminar de carregar, podemos ter um site meio travado. Então usamos uma função assíncrona para nosso site poder carregar tudo o que precisa e, quando a requisição chegar, apenas atualizamos o site com essas informações que vieram.

Dessa forma, o carregamento do site ocorre em paralelo com a busca das informações. Tendo um carregamento de página mais fluída.

// Definimos a URL base
const tvmaze_link = 'https://api.tvmaze.com';

// Coloca o cursor no campo de pesquisa quando abre a página
document.addEventListener("DOMContentLoaded", () => {
    const inputField = document.getElementById("search");
    inputField.focus();
});

// Trata o submit do formulário
mySubmitHandler = async (event) => {
    event.preventDefault();

    // criamos a URL e adicionamos o endpoint
    const url = new URL(tvmaze_link + '/search/shows');

    // Pegamos o parâmetro de pesquisa digitado pelo usuário
    const text = document.getElementById("search").value;

    // Adicionamos o parâmetro na busca
    url.search = new URLSearchParams({
        q: text,
    }).toString();

    try {
        // Fazemos a chamada ao serviço web
        const response = await fetch(url, {
            method: "GET",
            dataType: "json",
        });
        const result = await response.json();
        const movies = document.getElementById("movies");

        // Resetamos o conteúdo da tabela
        movies.innerHTML = "";

        // E colocamos o resultado da pesquisa atual
        result.forEach(element => {
            movies.appendChild(getTableRow(element));
        });
    } catch (error) {
        alert("Error: " + error);
    }
}

getTableRow = (element) => {
    // Criamos uma tag HTML tipo TR
    const tr = document.createElement("tr");

    // E construímos o conteúdo com as informações do objeto
    tr.innerHTML = (`
        <td>
            <img src="${element.show.image.medium}" width=50>
        </td>
        <td>
            ${element.show.name}
        </td>
        <td>
            <a href="${element.show.url}" target="_blank">
                ${element.show.url}
            </a>
        </td>
    `);
    return tr;
}

Como forma opcional, podemos usar a biblioteca JQuery também. Segue um exemplo:

Atividade

Implemente uma página web que consuma alguma outra API de sua escolha. A API (back-end) pode até ser desenvolvida por você.