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.