S
SolidJS3mo 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
brenelz3mo 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
TaQuanMinhLong3mo 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
peerreynders3mo 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
Rodrigo3mo ago
Thank you so much @peerreynders @TaQuanMinhLong and @TaQuanMinhLong ! This has been enlightening!
Want results from more Discord servers?
Add your server