Creating Async Components (AJAX & APIs)

CellUI operates synchronously for blazingly fast mounting. If a component needs to download data from a remote server before rendering, you should compose it using CellUI's when() conditional.

We achieve this with the "Loading Signal" Pattern.

Pattern: The Async Loader

import { signal, when, view, effect } from '@cmj/cellui';

function UserProfile(userId: number) {
  // 1. State for Data
  const user = signal<{ name: string; avatar: string } | null>(null);
  
  // 2. State for Loading UI
  const isLoading = signal(true);
  const error = signal<string | null>(null);

  // 3. The Side Effect (AJAX Fetch)
  effect(async () => {
    try {
      isLoading.value = true;
      const response = await fetch(`https://api.example.com/users/${userId}`);
      user.value = await response.json();
    } catch (e) {
      error.value = "Failed to load user.";
    } finally {
      isLoading.value = false;
    }
  });

  // 4. Composing the UI States
  return view`
    <div class="profile-widget">
      ${when(error, () => view`<div class="error">${error}</div>`)}
      
      ${when(isLoading, () => Spinner())}
      
      ${when(user, () => view`
        <div class="profile-header">
          <img src="${user.value!.avatar}" />
          <h2>Welcome, ${user.value!.name}</h2>
        </div>
      `)}
    </div>
  `;
}

This pattern guarantees that your component mounts instantly (preventing layout shifts) while smoothly transitioning between Loading, Error, and Success states entirely through O(1) granular updates.