#Is createAsync supposed to work with Suspense?

1 messages · Page 1 of 1 (latest)

languid sedge
#

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>
  )
}

Any ideas?

silent kettle
#

This is because result() is undefined until the promise resolves

silent kettle
#

The children of suspense actually run right away even if it holds to show the fallback

dry latch
#

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>

vague moon
#

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 };