Qwik presenta varias opciones para hacer fetch dependiendo del resultado que se quiera tener y del tipo de API
que se trate. Para los propósitos del curso, te voy a enseñar dos métodos que podemos usar para hacer fetch de una API que no es del tipo REST
, es decir, de las APIs en las que solo puedes hacer GET
.
Para todos los ejemplos, vamos a partir de que tenemos la siguiente función para hacer fetch. La pondré debajo de todo en el index.tsx
, pero no dudes en ponerla en un archivo aparte. Ya sabes, buenas prácticas y eso.
// Path: src/routes/index.tsx
export async function fetchCharacters(): Promise<[]> {
const response = await fetch("https://dummyjson.com/users");
if (!response.ok) {
throw new Error("Ha habido un error a la hora de hacer fetch");
}
const results = await response.json();
return results.users;
}
Si quieres hacer fetch a raíz de por ejemplo el click de un botón, lo puedes hacer de la siguiente manera:
// Path: src/routes/index.tsx
export default component$(() => {
const onLoadCharacters = $(async () => {
const characters = await fetchCharacters();
console.log(characters);
});
return (
<div>
<h1>Cómo hacer fetch con Qwik </h1>
<button onClick$={onLoadCharacters}>Hacer fetch de los personajes</button>
</div>
);
});
Aquí tienes un vídeo de su funcionamiento. Fíjate en que el script de JavaScript que tiene que ver con el fetch se carga tan solo si se clica el botón.Esto tiene que ver con los conceptos de Lazy Loading y serialización que hemos visto en las lecciones anteriores.
Si quisiéramos renderizar los personajes, lo podríamos hacer a través de map
. Lo que hacemos en la función del botón es pasarle el resultado del fetch como valor a una store, y así lo podemos ver.
// Path: src/routes/index.tsx
import { Character } from "~/types";
// Character como type lo he definido en un archivo aparte, porque era muy largo.
// Si quieres verlo, puedes verlo en el archivo types.d.ts de la carpeta types en el repo
interface CharactersProps {
characters: Character[];
}
export default component$(() => {
// Posibilidad 1
const allCharacters = useStore<CharactersProps>({ characters: [] });
const onLoadCharacters = $(async () => {
const characters = await fetchCharacters();
allCharacters.characters = characters;
});
return (
<div>
<h1>Cómo hacer fetch con Qwik </h1>
<button onClick$={onLoadCharacters}>Hacer fetch de los personajes</button>
{allCharacters.characters.map((character: Character) => (
<div key={character.id}>
<h2>{character.firstName}</h2>
<p>{character.email}</p>
<img src={character.image} alt={character.firstName} />
</div>
))}
</div>
);
});
Esta posibilidad es brutal, ya que nos permite hacer fetch desde el servidor y luego renderizarlo en la vista, y no verás en ningún momento que el cliente se ha descargado script alguno de JavaScript. Lo primero que tenemos que hacer es crear una función con routeLoader$
que nos permite ejecutar una función desde el servidor.
// Path: src/routes/index.tsx
export const useCharacters = routeLoader$(async () => {
try {
return await fetchCharacters();
} catch (error) {
console.error(
"An error occurred while fetching Simpsons characters:",
error
);
return [];
}
});
export default component$(() => {
const { value: characters } = useCharacters();
return (
<div>
<h1>Cómo hacer fetch con Qwik </h1>
{characters.map((character: Character) => (
<div key={character.id}>
<h2>{character.firstName}</h2>
<p>{character.email}</p>
<img src={character.image} alt={character.firstName} />
</div>
))}
</div>
);
});
export async function fetchCharacters(): Promise<[]> {
const response = await fetch("https://dummyjson.com/users");
if (!response.ok) {
throw new Error("Ha habido un error a la hora de hacer fetch");
}
const results = await response.json();
return results.users;
}
Con esto ya tienes una pequeña overview de cómo funciona el tema de fetch con Qwik y de todo su potencial al efectuarlo directamente desde el servidor. Esta era la última gran lección de este curso para principiantes, ¡así que ya solo toca la despedida!