S
SolidJS6mo ago
Rodrigo

Is createAsync supposed to work with Suspense?

My Suspense component is not working well with createAsync. Basically, anything iside the Suspense block is running even though the promise from createAsync hasn't finished. I've got a fairly simple setup that's failing and I'd love to understand if this is by design and expected, or something that I'm doing wrong, or a bug: Simple SolidJS app with Solid Router. No SSR, no SolidStart. Classic component routing. The result is an uncaught error stating result() is undefined...
const remoteCall = cache(async () => {
return new Promise(resolve => setTimeout(() => resolve({ foo: '1' }), 2000))
}, 'remote')

const TestComponent = () => {
const result = createAsync(() => remoteCall())

return (
<Suspense fallback={<div>Loading...</div>}>
<div>Foo is {result().foo}</div>
</Suspense>
)
}
const remoteCall = cache(async () => {
return new Promise(resolve => setTimeout(() => resolve({ foo: '1' }), 2000))
}, 'remote')

const TestComponent = () => {
const result = createAsync(() => remoteCall())

return (
<Suspense fallback={<div>Loading...</div>}>
<div>Foo is {result().foo}</div>
</Suspense>
)
}
Any ideas?
4 Replies
brenelz
brenelz6mo ago
This is because result() is undefined until the promise resolves The children of suspense actually run right away even if it holds to show the fallback
TaQuanMinhLong
TaQuanMinhLong6mo ago
Better do it with <Show> or <Switch/Match> component But as soon as your app has at least one <Suspense> wrapped, then any resource reading will trigger the nearest<Suspense>
peerreynders
peerreynders6mo ago
i.e.
// file: src/routes/about.tsx
import { Show, Suspense } from 'solid-js';
import { cache, createAsync } from '@solidjs/router';
import { Title } from '@solidjs/meta';

function fakeRC() {
return new Promise<{ foo: number }>((resolve) =>
setTimeout(resolve, 2000, { foo: 1 })
);
}

const remoteCall = cache(fakeRC, 'remote');

function About() {
const result = createAsync(() => remoteCall());

return (
<main>
<Title>About</Title>
<h1>About</h1>
<Suspense fallback={<div>Loading…</div>}>
<Show when={result()}>
{(value) => <div>Foo is {value().foo}</div>}
</Show>
</Suspense>
</main>
);
}

export { About };
// file: src/routes/about.tsx
import { Show, Suspense } from 'solid-js';
import { cache, createAsync } from '@solidjs/router';
import { Title } from '@solidjs/meta';

function fakeRC() {
return new Promise<{ foo: number }>((resolve) =>
setTimeout(resolve, 2000, { foo: 1 })
);
}

const remoteCall = cache(fakeRC, 'remote');

function About() {
const result = createAsync(() => remoteCall());

return (
<main>
<Title>About</Title>
<h1>About</h1>
<Suspense fallback={<div>Loading…</div>}>
<Show when={result()}>
{(value) => <div>Foo is {value().foo}</div>}
</Show>
</Suspense>
</main>
);
}

export { About };
Rodrigo
RodrigoOP6mo ago
Thank you so much @peerreynders @TaQuanMinhLong and @TaQuanMinhLong ! This has been enlightening!
Want results from more Discord servers?
Add your server