{"id":1637,"date":"2024-08-02T10:49:51","date_gmt":"2024-08-02T08:49:51","guid":{"rendered":"https:\/\/blog.sutilweb.eu\/?page_id=1637"},"modified":"2024-08-02T10:49:52","modified_gmt":"2024-08-02T08:49:52","slug":"008-buscador-de-shows-con-fetch-y-tvmaze-api","status":"publish","type":"page","link":"https:\/\/sutilweb.eu\/index.php\/lenguajes\/javascript\/javascript-practico\/17-ejercicios-con-ajax\/008-buscador-de-shows-con-fetch-y-tvmaze-api\/","title":{"rendered":"008. Buscador de Shows con Fetch y TVMAZE API"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">En este cap\u00edtulo vamos a utilizar la <strong>API<\/strong> de <strong>TVMAZE<\/strong>, que se trata de una p\u00e1gina donde publican sobre todo shows de televisi\u00f3n en EEUU, con toda la informaci\u00f3n de en qu\u00e9 canales, a que fechas, a qu\u00e9 horas&#8230;<\/p>\n\n\n\n<!--more-->\n\n\n\n<p class=\"wp-block-paragraph\"><strong>TVMAZE<\/strong> tiene una <strong>API<\/strong> p\u00fablica con la que podemos hacer diferentes cosas, aunque nos enfocaremos en mostrar los shows a partir de una b\u00fasqueda, es decir, vamos a hacer un <strong>buscador din\u00e1mico<\/strong>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Para ello vamos a ir al editor que estemos utilizando (recomendamos <a href=\"https:\/\/code.visualstudio.com\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Visual Studio Code<\/strong><\/a>) y creamos un archivo denominado <em>api-tv-shows.html<\/em>, que contendr\u00e1 el siguiente c\u00f3digo.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">&lt;!DOCTYPE html&gt;\n&lt;html lang=\"es\"&gt;\n&nbsp; &lt;head&gt;\n&nbsp; &nbsp; &lt;meta charset=\"UTF-8\" \/&gt;\n&nbsp; &nbsp; &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/&gt;\n&nbsp; &nbsp; &lt;title&gt;Buscador de shows de TV&lt;\/title&gt;\n&nbsp; &nbsp; &lt;style&gt;\n&nbsp; &nbsp; &nbsp; .grid-fluid {\n&nbsp; &nbsp; &nbsp; &nbsp; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; .loader {\n&nbsp; &nbsp; &nbsp; &nbsp; display: block;\n&nbsp; &nbsp; &nbsp; &nbsp; margin: auto;\n&nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &lt;\/style&gt;\n&nbsp; &lt;\/head&gt;\n\n&nbsp; &lt;body&gt;\n&nbsp; &nbsp; &lt;h1&gt;Buscador de shows de TV&lt;\/h1&gt;\n&nbsp; &nbsp; &lt;input type=\"search\" name=\"\" id=\"search\" placeholder=\"Buscar shows...\" \/&gt;\n\n&nbsp; &nbsp; &lt;section id=\"shows\" class=\"grid-fluid\"&gt;&lt;\/section&gt;\n&nbsp; &nbsp; &lt;template id=\"show-template\"&gt;\n&nbsp; &nbsp; &nbsp; &lt;article class=\"show\"&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;h3&gt;&lt;\/h3&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;div&gt;&lt;\/div&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;img \/&gt;\n&nbsp; &nbsp; &nbsp; &nbsp; &lt;a&gt;&lt;\/a&gt;\n&nbsp; &nbsp; &nbsp; &lt;\/article&gt;\n&nbsp; &nbsp; &lt;\/template&gt;\n\n&nbsp; &nbsp; &lt;script&gt;\n&nbsp; &nbsp; &nbsp; const d = document,\n&nbsp; &nbsp; &nbsp; &nbsp; $shows = d.getElementById(\"shows\"),\n&nbsp; &nbsp; &nbsp; &nbsp; $template = d.getElementById(\"show-template\").content,\n&nbsp; &nbsp; &nbsp; &nbsp; $fragment = d.createDocumentFragment();\n\n&nbsp; &nbsp; &nbsp; d.addEventListener(\"keypress\", async (e) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; if (e.target.matches(\"#search\")) {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (e.key === \"Enter\") {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $shows.innerHTML = `&lt;img class=\"loader\" src=\".\/loader.svg\" alt=\"cargando\"&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let query = e.target.value.toLowerCase(),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; api = `https:\/\/api.tvmaze.com\/search\/shows?q=${query}`,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; res = await fetch(api),\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; json = await res.json();\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ &nbsp; console.log(api, res, json);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!res.ok)\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status: res.status,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; statusText: res.statusText,\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (json.lenght === 0) {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $shows.innerHTML = `&lt;h2&gt;No existen resultados de shows para el criterio de b\u00fasqueda: ${query}&lt;\/h2&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; json.forEach((el) =&gt; {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"h3\").textContent = el.show.name;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"div\").innerHTML = el.show.summary\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? el.show.summary\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : \"Sin descripci\u00f3n\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"img\").src = el.show.image\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? el.show.image.medium\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : \"No img\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"img\").alt = el.show.name;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"img\").style.maxWidth = \"100%\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"a\").href = el.show.url\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? el.show.url\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : \"#\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"a\").target = el.show.url\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? \"_blank\"\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : \"_self\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $template.querySelector(\"a\").textContent = el.show.url\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ? \"Ver m\u00e1s...\"\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : \"\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let $clone = d.importNode($template, true);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fragment.appendChild($clone);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $shows.innerHTML = \"\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $shows.appendChild($fragment);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (err) {\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.log(err);\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; let message = err.statusText || \"Ocurri\u00f3 un error\";\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $shows.innerHTML = `&lt;p&gt;Error ${err.status}: ${message}&lt;\/p&gt;`;\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; &nbsp; }\n&nbsp; &nbsp; &nbsp; });\n&nbsp; &nbsp; &lt;\/script&gt;\n&nbsp; &lt;\/body&gt;\n&lt;\/html&gt;<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>En este cap\u00edtulo vamos a utilizar la API de TVMAZE, que se trata de una p\u00e1gina donde publican sobre todo shows de&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":1609,"menu_order":7,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_uag_custom_page_level_css":"","footnotes":""},"class_list":["post-1637","page","type-page","status-publish","hentry"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Sutil Web","author_link":"https:\/\/sutilweb.eu\/index.php\/author\/sutilweb\/"},"uagb_comment_info":0,"uagb_excerpt":"En este cap\u00edtulo vamos a utilizar la API de TVMAZE, que se trata de una p\u00e1gina donde publican sobre todo shows de...","_links":{"self":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1637","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/comments?post=1637"}],"version-history":[{"count":2,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1637\/revisions"}],"predecessor-version":[{"id":1639,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1637\/revisions\/1639"}],"up":[{"embeddable":true,"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/pages\/1609"}],"wp:attachment":[{"href":"https:\/\/sutilweb.eu\/index.php\/wp-json\/wp\/v2\/media?parent=1637"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}