Async values
Load data with an async computed, and show it with @try, @pending, and @catch.
A handle points at an element as soon as the element is on the page. Data from the network takes longer, so the page needs a plan for the wait.
Give computed() an async function. Then put every read of it inside @try. Add @pending for the wait and @catch for a failure.
At build time, the compiler finds the async recipe and the three blocks. In the browser, the page shows @pending first. Your function loads the data, and the @try content replaces @pending.
If you render pages on a server, as @markless/router apps do, one thing changes. Fast data arrives with the page. Slow data sends @pending first, and the data follows in the same response.
Click Load the page in the figure.
What does the reader see while data loads?
Press Load the page, or drag the timeline. Then pick On a server and watch which steps stay the same.
Markless builds the page in the browser. The data is not here yet, so the page shows the @pending content.
Loading
import { computed, state } from '@markless/core';import { loadGreeting } from './greeting.ts'; export default function Greeting() @{ let name = state('Ada'); const details = computed(async ({ signal }) => { (waits for data) const who = name; return { title: await loadGreeting(who, signal) }; }); <section> @try { <p>{details.title}</p> } @pending { <p>Loading</p> (on screen) } @catch { <p>Could not load</p> } </section>}- updatedShowed the
@pendingcontent: “Loading”.
Simplified. A server is optional: the browser alone runs this. On a server, data that is ready fast arrives with the page, so the reader never sees Loading.
Notice that the reader sees @pending first and the data second, in the browser and on a server.
import { computed, state } from '@markless/core';
import { loadGreeting } from './greeting.ts';
export default function Greeting() @{
let name = state('Ada');
const details = computed(async ({ signal }) => {
const who = name;
return { title: await loadGreeting(who, signal) };
});
<section>
@try {
<p>{details.title}</p>
} @pending {
<p>Loading</p>
} @catch {
<p>Could not load</p>
}
</section>
}
Inside @try, read the result directly: details.title. loadGreeting is your own function in a .ts file.
When name changes, the computed runs again. Markless cancels the old run through signal, so pass signal to your fetch. The old text stays on screen while the new data loads. If the wait gets long, @pending can show again.
Next: How does a choice like theme survive a page reload? Storage →
