Data Fetching

Examples demonstrating how to fetch and display data from APIs using Element's reactive system.

import {
  createEffect,
  createSignal,
  For,
  html,
  If,
  IfOrElse,
} from "@dmnchzl/element";

interface User {
  id: number;
  name: string;
  email: string;
  phone: string;
}

function UserList() {
  const [abortCtrl, setAbortCtrl] = createSignal<AbortController | null>(null);
  const [users, setUsers] = createSignal<User[]>([]);
  const [loading, setLoading] = createSignal(false);
  const [error, setError] = createSignal<string | null>(null);

  const fetchUsers = async () => {
    const ctrl = new AbortController();
    setAbortCtrl(ctrl);

    setLoading(true);
    setError(null);

    try {
      const response = await fetch(
        "https://jsonplaceholder.typicode.com/users",
        { signal: ctrl.signal }
      );
      if (!response.ok) {
        throw new Error(`HTTP Status Error: ${response.status}`);
      }
      const data = await response.json();
      setUsers(data);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Something Went Wrong!");
    } finally {
      setLoading(false);
    }
  };

  createEffect(() => {
    fetchUsers();
    return () => {
      const ctrl = abortCtrl();
      if (ctrl) ctrl.abort();
    };
  });

  return html`
    <div class="container">
      <h1>User</h1>
      ${IfOrElse(
        loading,
        (isLoading) => html`<div>Loading...</div>`,
        () => html`<ul class="user-list">
          ${For(
            users,
            (user, index) => html`<li key="${index}">
              <div class="user-item">
                <span>${user.name}</span>
                <span>${user.email}</span>
                <span>${user.phone}</span>
              </div>
            </li>`
          )}
        </ul>`
      )}${If(
        error,
        (message) => html`<button onclick="${fetchUsers}">${message}</button>`
      )}
    </div>
  `;
}

document.body.appendChild(UserList());

Last updated